home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.014 / samba-1
Encoding:
Text File  |  1995-07-01  |  70.4 KB  |  2,458 lines

  1. diff -u -r --new-file last-version/examples/tridge/README samba-1.9.14alpha4/examples/tridge/README
  2. --- last-version/examples/tridge/README    Thu Jun 29 16:42:40 1995
  3. +++ samba-1.9.14alpha4/examples/tridge/README    Sat Jul  1 13:23:17 1995
  4. @@ -1,4 +1,8 @@
  5.  This is the configuration I use at home. I have 2 client PCs, one
  6. -running Win95, one running alternately WfWg and NTAS3.5.
  7. +running Win95, one running alternately WfWg and NTAS3.5. My server is
  8. +a 486dx2-66 Linux box.
  9.  
  10. -My server is a 486dx266 Linux box.
  11. +Note that I use the %a and %m macros to load smb.conf extensions
  12. +particular to machines and architectures. This gives me a lot of
  13. +flexibility in how I handle each of the machines.
  14. +
  15. diff -u -r --new-file last-version/source/change-log samba-1.9.14alpha4/source/change-log
  16. --- last-version/source/change-log    Sat Jul  1 01:12:19 1995
  17. +++ samba-1.9.14alpha4/source/change-log    Sat Jul  1 15:05:38 1995
  18. @@ -1471,6 +1471,10 @@
  19.      - aix qconfig parsing from Jean-Pierre.Boulard@univ-rennes1.fr
  20.      - more long_date fixups
  21.      - added wildcards to nmbd
  22. +    - extensive changes to ipc.c and miscellaneous other changes 
  23. +    from ad@papyrus.hamburg.com (Andreas Degert). Should especially
  24. +    help OS/2 users
  25. +    
  26.  
  27.  ==========
  28.  todo:
  29. diff -u -r --new-file last-version/source/ipc.c samba-1.9.14alpha4/source/ipc.c
  30. --- last-version/source/ipc.c    Thu Jun 29 18:18:16 1995
  31. +++ samba-1.9.14alpha4/source/ipc.c    Sat Jul  1 14:58:44 1995
  32. @@ -17,11 +17,11 @@
  33.     You should have received a copy of the GNU General Public License
  34.     along with this program; if not, write to the Free Software
  35.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36. -*/
  37. +   */
  38.  /*
  39.     This file handles the named pipe and mailslot calls
  40.     in the SMBtrans protocol
  41. -*/
  42. +   */
  43.  
  44.  
  45.  #include "includes.h"
  46. @@ -33,6 +33,7 @@
  47.  extern files_struct Files[];
  48.  
  49.  extern fstring local_machine;
  50. +extern BOOL lpq_cache_reset;
  51.  
  52.  #define NERR_Success 0
  53.  #define NERR_badpass 86
  54. @@ -40,14 +41,74 @@
  55.  
  56.  #define NERR_BASE (2100)
  57.  #define NERR_BufTooSmall (NERR_BASE+23)
  58. +#define NERR_JobNotFound (NERR_BASE+51)
  59. +#define NERR_DestNotFound (NERR_BASE+52)
  60. +#define ERROR_INVALID_LEVEL 124
  61. +#define ERROR_MORE_DATA 234
  62. +
  63. +#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
  64. +
  65. +#define ACCESS_READ 0x01
  66. +#define ACCESS_WRITE 0x02
  67. +#define ACCESS_CREATE 0x04
  68. +
  69. +#define STYPE_DISKTREE    0    /* Disk drive */
  70. +#define STYPE_PRINTQ    1    /* Spooler queue */
  71. +#define STYPE_DEVICE    2    /* Serial device */
  72. +#define STYPE_IPC    3    /* Interprocess communication (IPC) */
  73. +
  74. +#define SHPWLEN 8        /* share password length */
  75. +#define NNLEN 12        /* 8.3 net name length */
  76. +#define SNLEN 15        /* service name length */
  77. +#define QNLEN 12        /* queue name maximum length */
  78.  
  79. -#define REALLOC(ptr,size) Realloc(ptr,MAX((size),1024))
  80. +static int CopyExpanded(int cnum, int snum, char** dst, char* src, int* n)
  81. +{
  82. +  pstring buf;
  83. +  int l;
  84. +  strcpy(buf,src);
  85. +  string_sub(buf,"%S",lp_servicename(snum));
  86. +  standard_sub(cnum,buf);
  87. +  StrnCpy(*dst,buf,*n);
  88. +  l = strlen(*dst) + 1;
  89. +  *dst += l;
  90. +  *n -= l;
  91. +  return l;
  92. +}
  93. +
  94. +static int CopyAndAdvance(char** dst, char* src, int* n)
  95. +{
  96. +  int l;
  97. +  StrnCpy(*dst,src,*n);
  98. +  l = strlen(*dst) + 1;
  99. +  *dst += l;
  100. +  *n -= l;
  101. +  return l;
  102. +}
  103. +
  104. +static int StrlenExpanded(int cnum, int snum, char* s)
  105. +{
  106. +  pstring buf;
  107. +  strcpy(buf,s);
  108. +  string_sub(buf,"%S",lp_servicename(snum));
  109. +  standard_sub(cnum,buf);
  110. +  return strlen(buf) + 1;
  111. +}
  112. +
  113. +static char* Expand(int cnum, int snum, char* s)
  114. +{
  115. +  static pstring buf;
  116. +  strcpy(buf,s);
  117. +  string_sub(buf,"%S",lp_servicename(snum));
  118. +  standard_sub(cnum,buf);
  119. +  return buf;
  120. +}
  121.  
  122.  /****************************************************************************
  123. -send a trans reply
  124. -****************************************************************************/
  125. +  send a trans reply
  126. +  ****************************************************************************/
  127.  static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup,
  128. -              int ldata,int lparam,int lsetup)
  129. +                 int ldata,int lparam,int lsetup)
  130.  {
  131.    int i;
  132.    int this_ldata,this_lparam;
  133. @@ -115,295 +176,693 @@
  134.  
  135.  
  136.  /****************************************************************************
  137. -get a print queue
  138. -Normal form: (uLevel=2) <zWrLh> <B13BWWWzzzzzWN> 
  139. -Alternate (uLevel=0): <zWrLh> <B13> 
  140. -****************************************************************************/
  141. +  get a print queue
  142. +  ****************************************************************************/
  143. +
  144. +struct pack_desc {
  145. +  char* format;            /* formatstring for structure */
  146. +  char* subformat;        /* subformat for structure */
  147. +  char* base;            /* baseaddress of buffer */
  148. +  int buflen;            /* remaining size for fixed part; on init: length of base */
  149. +  int subcount;            /* count of substructures */
  150. +  char* structbuf;        /* pointer into buffer for remaining fixed part */
  151. +  int stringlen;        /* remaining size for variable part */        
  152. +  char* stringbuf;        /* pointer into buffer for remaining variable part */
  153. +  int neededlen;        /* total needed size */
  154. +  int usedlen;            /* total used size (usedlen <= neededlen and usedlen <= buflen) */
  155. +  char* curpos;            /* current position; pointer into format or subformat */
  156. +  int errcode;
  157. +};
  158. +
  159. +static int get_counter(char** p)
  160. +{
  161. +  int i, n;
  162. +  if (!isdigit(**p)) return 1;
  163. +  for (n = 0;;) {
  164. +    i = **p;
  165. +    if (isdigit(i))
  166. +      n = 10 * n + (i - '0');
  167. +    else
  168. +      return n;
  169. +    (*p)++;
  170. +  }
  171. +}
  172. +
  173. +static int getlen(char* p)
  174. +{
  175. +  int n = 0;
  176. +  while (*p) {
  177. +    switch( *p++ ) {
  178. +    case 'W':            /* word (2 byte) */
  179. +      n += 2;
  180. +      break;
  181. +    case 'N':            /* count of substructures (word) at end */
  182. +      n += 2;
  183. +      break;
  184. +    case 'D':            /* double word (4 byte) */
  185. +    case 'z':            /* offset to zero terminated string (4 byte) */
  186. +    case 'l':            /* offset to user data (4 byte) */
  187. +      n += 4;
  188. +      break;
  189. +    case 'b':            /* offset to data (with counter) (4 byte) */
  190. +      n += 4;
  191. +      get_counter(&p);
  192. +      break;
  193. +    case 'B':            /* byte (with optional counter) */
  194. +      n += get_counter(&p);
  195. +      break;
  196. +    }
  197. +  }
  198. +  return n;
  199. +}
  200. +
  201. +static void init_package(struct pack_desc* p, int count, int subcount)
  202. +{
  203. +  int n = p->buflen;
  204. +  int i = count * getlen(p->format);
  205. +  if (p->subformat) i += subcount * getlen(p->subformat);
  206. +  p->structbuf = p->base;
  207. +  p->neededlen = 0;
  208. +  p->usedlen = 0;
  209. +  p->subcount = 0;
  210. +  p->curpos = p->format;
  211. +  if (i > n) {
  212. +    i = n = 0;
  213. +    p->errcode = NERR_BufTooSmall;
  214. +  }
  215. +  else
  216. +    p->errcode = NERR_Success;
  217. +  p->buflen = i;
  218. +  n -= i;
  219. +  p->stringbuf = p->base + i;
  220. +  p->stringlen = n;
  221. +}
  222. +
  223. +static int package(struct pack_desc* p, ...)
  224. +{
  225. +  va_list args;
  226. +  int needed=0, stringneeded;
  227. +  char* str=NULL;
  228. +  int is_string=0, stringused;
  229. +  va_start(args,p);
  230. +  if (!*p->curpos) {
  231. +    if (!p->subcount)
  232. +      p->curpos = p->format;
  233. +    else {
  234. +      p->curpos = p->subformat;
  235. +      p->subcount--;
  236. +    }
  237. +  }
  238. + #if CHECK_TYPES
  239. +  str = va_arg(args,char*);
  240. +  if (strncmp(str,p->curpos,strlen(str)) != 0) {
  241. +    DEBUG(2,("type error in package: %s instead of %*s in %s/%s\n",str,
  242. +          strlen(str),p->curpos,p->format1,p->format2));
  243. +    return 0;
  244. +  }
  245. + #endif
  246. +  stringneeded = -1;
  247. +  switch( *p->curpos++ ) {
  248. +  case 'W':            /* word (2 byte) */
  249. +    needed = 2;
  250. +    if (p->buflen >= needed) SSVAL(p->structbuf,0,va_arg(args,int16));
  251. +    break;
  252. +  case 'N':            /* count of substructures (word) at end */
  253. +    needed = 2;
  254. +    p->subcount = va_arg(args,int16);
  255. +    if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
  256. +    break;
  257. +  case 'D':            /* double word (4 byte) */
  258. +    needed = 4;
  259. +    if (p->buflen >= needed) SIVAL(p->structbuf,0,va_arg(args,int32));
  260. +    break;
  261. +  case 'B':            /* byte (with optional counter) */
  262. +    needed = get_counter(&p->curpos);
  263. +    if (p->buflen >= needed) StrnCpy(p->structbuf,va_arg(args,char*),needed);
  264. +    break;
  265. +  case 'z':            /* offset to zero terminated string (4 byte) */
  266. +    str = va_arg(args,char*);
  267. +    stringneeded = (str ? strlen(str)+1 : 0);
  268. +    is_string = 1;
  269. +    break;
  270. +  case 'l':            /* offset to user data (4 byte) */
  271. +    str = va_arg(args,char*);
  272. +    stringneeded = va_arg(args,int);
  273. +    is_string = 0;
  274. +    break;
  275. +  case 'b':            /* offset to data (with counter) (4 byte) */
  276. +    str = va_arg(args,char*);
  277. +    stringneeded = get_counter(&p->curpos);
  278. +    is_string = 0;
  279. +    break;
  280. +  }
  281. +  va_end(args);
  282. +  if (stringneeded >= 0) {
  283. +    needed = 4;
  284. +    if (p->buflen >= needed) {
  285. +      stringused = stringneeded;
  286. +      if (stringused > p->stringlen) {
  287. +    stringused = (is_string ? p->stringlen : 0);
  288. +    if (p->errcode == NERR_Success) p->errcode = ERROR_MORE_DATA;
  289. +      }
  290. +      if (!stringused)
  291. +    SIVAL(p->structbuf,0,0);
  292. +      else {
  293. +    SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
  294. +    memcpy(p->stringbuf,str,stringused);
  295. +    if (is_string) p->stringbuf[stringused-1] = '\0';
  296. +    p->stringbuf += stringused;
  297. +    p->stringlen -= stringused;
  298. +    p->usedlen += stringused;
  299. +      }
  300. +    }
  301. +    p->neededlen += stringneeded;
  302. +  }
  303. +  p->neededlen += needed;
  304. +  if (p->buflen >= needed) {
  305. +    p->structbuf += needed;
  306. +    p->buflen -= needed;
  307. +    p->usedlen += needed;
  308. +  }
  309. +  else {
  310. +    if (p->errcode == NERR_Success) p->errcode = NERR_BufTooSmall;
  311. +  }
  312. +  return 1;
  313. +}
  314. +
  315. +#if CHECK_TYPES
  316. +#define PACK(desc,t,v) package(desc,t,v)
  317. +#define PACKl(desc,t,v,l) package(desc,t,v,l)
  318. +#else
  319. +#define PACK(desc,t,v) package(desc,v)
  320. +#define PACKl(desc,t,v,l) package(desc,v,l)
  321. +#endif
  322. +
  323. +static void PackDriverData(struct pack_desc* desc)
  324. +{
  325. +  char drivdata[4+4+32];
  326. +  SIVAL(drivdata,0,sizeof drivdata); /* cb */
  327. +  SIVAL(drivdata,4,1000);    /* lVersion */
  328. +  memset(drivdata+8,0,32);    /* szDeviceName */
  329. +  strcpy(drivdata+8,"IBMNULL");
  330. +  PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
  331. +}
  332. +
  333. +static int check_printq_info(struct pack_desc* desc,
  334. +                  int uLevel, const char* id1, const char* id2)
  335. +{
  336. +  desc->subformat = NULL;
  337. +  switch( uLevel ) {
  338. +  case 0:
  339. +    desc->format = "B13";
  340. +    break;
  341. +  case 1:
  342. +    desc->format = "B13BWWWzzzzzWW";
  343. +    break;
  344. +  case 2:
  345. +    desc->format = "B13BWWWzzzzzWN";
  346. +    desc->subformat = "WB21BB16B10zWWzDDz";
  347. +    break;
  348. +  case 3:
  349. +    desc->format = "zWWWWzzzzWWzzl";
  350. +    break;
  351. +  case 4:
  352. +    desc->format = "zWWWWzzzzWNzzl";
  353. +    desc->subformat = "WWzWWDDzz";
  354. +    break;
  355. +  case 5:
  356. +    desc->format = "z";
  357. +    break;
  358. +  default: return False;
  359. +  }
  360. +  if (strcmp(desc->format,id1) != 0) return False;
  361. +  if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
  362. +  return True;
  363. +}
  364. +
  365. +static void fill_printjob_info(int cnum, int snum, int uLevel,
  366. +                   struct pack_desc* desc,
  367. +                   print_queue_struct* queue, int n)
  368. +{
  369. +  PACK(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */
  370. +  if (uLevel == 1) {
  371. +    PACK(desc,"B21",queue->user); /* szUserName */
  372. +    PACK(desc,"B",0);        /* pad */
  373. +    PACK(desc,"B16","");    /* szNotifyName */
  374. +    PACK(desc,"B10","PM_Q_RAW"); /* szDataType */
  375. +    PACK(desc,"z","");        /* pszParms */
  376. +    PACK(desc,"W",n+1);        /* uPosition */
  377. +    PACK(desc,"W",queue->status); /* fsStatus */
  378. +    PACK(desc,"z","");        /* pszStatus */
  379. +    PACK(desc,"D",queue->time); /* ulSubmitted */
  380. +    PACK(desc,"D",queue->size); /* ulSize */
  381. +    PACK(desc,"z",queue->file); /* pszComment */
  382. +  }
  383. +  if (uLevel == 2 || uLevel == 3) {
  384. +    PACK(desc,"W",50);        /* uPriority */
  385. +    PACK(desc,"z",queue->user); /* pszUserName */
  386. +    PACK(desc,"W",n+1);        /* uPosition */
  387. +    PACK(desc,"W",queue->status); /* fsStatus */
  388. +    PACK(desc,"D",queue->time); /* ulSubmitted */
  389. +    PACK(desc,"D",queue->size); /* ulSize */
  390. +    PACK(desc,"z","Samba");    /* pszComment */
  391. +    PACK(desc,"z",queue->file); /* pszDocument */
  392. +    if (uLevel == 3) {
  393. +      PACK(desc,"z","");    /* pszNotifyName */
  394. +      PACK(desc,"z","PM_Q_RAW"); /* pszDataType */
  395. +      PACK(desc,"z","");    /* pszParms */
  396. +      PACK(desc,"z","");    /* pszStatus */
  397. +      PACK(desc,"z",SERVICE(snum)); /* pszQueue */
  398. +      PACK(desc,"z","lpd");    /* pszQProcName */
  399. +      PACK(desc,"z","");    /* pszQProcParms */
  400. +      PACK(desc,"z","IBMNULL"); /* pszDriverName */
  401. +      PackDriverData(desc);    /* pDriverData */
  402. +      PACK(desc,"z","");    /* pszPrinterName */
  403. +    }
  404. +  }
  405. +}
  406. +
  407. +static void fill_printq_info(int cnum, int snum, int uLevel,
  408. +                  struct pack_desc* desc,
  409. +                  int count, print_queue_struct* queue,
  410. +                  print_status_struct* status)
  411. +{
  412. +  if (uLevel < 3)
  413. +    PACK(desc,"B13",SERVICE(snum));
  414. +  else
  415. +    PACK(desc,"z",Expand(cnum,snum,SERVICE(snum)));
  416. +  if (uLevel == 1 || uLevel == 2) {
  417. +    PACK(desc,"B",0);        /* alignment */
  418. +    PACK(desc,"W",5);        /* priority */
  419. +    PACK(desc,"W",0);        /* start time */
  420. +    PACK(desc,"W",0);        /* until time */
  421. +    PACK(desc,"z","");        /* pSepFile */
  422. +    PACK(desc,"z","lpd");    /* pPrProc */
  423. +    PACK(desc,"z",SERVICE(snum)); /* pDestinations */
  424. +    PACK(desc,"z",0);        /* pParms */
  425. +    if (snum < 0) {
  426. +      PACK(desc,"z","UNKNOWN PRINTER");
  427. +      PACK(desc,"W",LPSTAT_ERROR);
  428. +    }
  429. +    else if (!status->message[0]) {
  430. +      PACK(desc,"z",Expand(cnum,snum,lp_comment(snum)));
  431. +      PACK(desc,"W",LPSTAT_OK); /* status */
  432. +    }
  433. +    else {
  434. +      PACK(desc,"z",status->message);
  435. +      PACK(desc,"W",status->status); /* status */
  436. +    }
  437. +    PACK(desc,(uLevel == 1 ? "W" : "N"),count);
  438. +  }
  439. +  if (uLevel == 3 || uLevel == 4) {
  440. +    PACK(desc,"W",5);        /* uPriority */
  441. +    PACK(desc,"W",0);        /* uStarttime */
  442. +    PACK(desc,"W",0);        /* uUntiltime */
  443. +    PACK(desc,"W",5);        /* pad1 */
  444. +    PACK(desc,"z","");        /* pszSepFile */
  445. +    PACK(desc,"z","lpd");    /* pszPrProc */
  446. +    PACK(desc,"z","");        /* pszParms */
  447. +    if (!status->message[0]) {
  448. +      PACK(desc,"z",Expand(cnum,snum,lp_comment(snum))); /* pszComment */
  449. +      PACK(desc,"W",LPSTAT_OK); /* fsStatus */
  450. +    }
  451. +    else {
  452. +      PACK(desc,"z",status->message); /* pszComment */
  453. +      PACK(desc,"W",status->status); /* fsStatus */
  454. +    }
  455. +    PACK(desc,(uLevel == 3 ? "W" : "N"),count);    /* cJobs */
  456. +    PACK(desc,"z",SERVICE(snum)); /* pszPrinters */
  457. +    PACK(desc,"z","IBMNULL");    /* pszDriverName */
  458. +    PackDriverData(desc);    /* pDriverData */
  459. +  }
  460. +  if (uLevel == 2 || uLevel == 4) {
  461. +    int i;
  462. +    for (i=0;i<count;i++)
  463. +      fill_printjob_info(cnum,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
  464. +  }
  465. +  DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",SERVICE(snum),count));
  466. +}
  467. +
  468.  static BOOL api_DosPrintQGetInfo(int cnum,char *param,char *data,
  469. -                  int mdrcnt,int mprcnt,
  470. -                  char **rdata,char **rparam,
  471. -                  int *rdata_len,int *rparam_len)
  472. +                 int mdrcnt,int mprcnt,
  473. +                 char **rdata,char **rparam,
  474. +                 int *rdata_len,int *rparam_len)
  475.  {
  476.    char *str1 = param+2;
  477.    char *str2 = skip_string(str1,1);
  478.    char *p = skip_string(str2,1);
  479.    char *QueueName = p;
  480.    int uLevel,cbBuf;
  481. -  int count=0;
  482. -  int i;
  483. -  print_queue_struct *queue=NULL;
  484. -  char *p2=NULL;
  485. +  int count;
  486.    int snum;
  487. +  char* str3;
  488. +  struct pack_desc desc;
  489. +  print_queue_struct *queue=NULL;
  490.    print_status_struct status;
  491. -
  492. -  status.message = NULL;
  493. -
  494. +  
  495. +  bzero(&status,sizeof(status));
  496.    p = skip_string(p,1);
  497.    uLevel = SVAL(p,0);
  498.    cbBuf = SVAL(p,2);
  499. -
  500. -  if ((p = strchr(QueueName,'%')))
  501. -    *p = 0;
  502. -
  503. +  str3 = p + 4;
  504. +  if ((p = strchr(QueueName,'%'))) *p = 0;
  505.    DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
  506. -
  507.    /* check it's a supported varient */
  508. -  if (!
  509. -      ((uLevel==2 && strcsequal(str1,"zWrLh") && strcsequal(str2,"B13BWWWzzzzzWN")) ||
  510. -       (uLevel==1 && strcsequal(str1,"zWrLh") && strcsequal(str2,"B13BWWWzzzzzWW")) ||
  511. -       (uLevel==3 && strcsequal(str1,"zWrLh") && strcsequal(str2,"zWWWWzzzzWWzzl")) || 
  512. -       (uLevel==0 && strcsequal(str1,"zWrLh") && strcsequal(str2,"B13"))))
  513. -    return(False);
  514. -
  515. +  if (strcmp(str1,"zWrLh") != 0) return False;
  516. +  if (!check_printq_info(&desc,uLevel,str2,str3)) return False;
  517.    snum = lp_servicenumber(QueueName);
  518. -  if (snum < 0 && pcap_printername_ok(QueueName,NULL))
  519. -    {
  520. -      int pnum = lp_servicenumber(PRINTERS_NAME);
  521. -      if (pnum >= 0)
  522. -    {
  523. -      lp_add_printer(QueueName,pnum);
  524. -      snum = lp_servicenumber(QueueName);
  525. -    }
  526. +  if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
  527. +    int pnum = lp_servicenumber(PRINTERS_NAME);
  528. +    if (pnum >= 0) {
  529. +      lp_add_printer(QueueName,pnum);
  530. +      snum = lp_servicenumber(QueueName);
  531.      }
  532. -      
  533. +  }
  534. +  
  535. +  count = get_printqueue(snum,cnum,&queue,&status);
  536. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  537. +  desc.base = *rdata;
  538. +  desc.buflen = mdrcnt;
  539. +  init_package(&desc,1,count);
  540. +  desc.subcount = count;
  541. +  fill_printq_info(cnum,snum,uLevel,&desc,count,queue,&status);
  542. +  *rdata_len = desc.usedlen;
  543. +  
  544. +  *rparam_len = 6;
  545. +  *rparam = REALLOC(*rparam,*rparam_len);
  546. +  SSVALS(*rparam,0,desc.errcode);
  547. +  SSVAL(*rparam,2,0);
  548. +  SSVAL(*rparam,4,desc.neededlen);
  549. +  
  550. +  DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
  551.  
  552. -  /* go and get the actual queue entries */
  553. -  if (snum >= 0 && uLevel >= 1)
  554. -    count = get_printqueue(snum,cnum,&queue,&status);
  555. +  if (queue) free(queue);
  556. +  
  557. +  return(True);
  558. +}
  559.  
  560. -  /* don't return too many entries for the buffer */
  561. -  if (uLevel != 1)
  562. -    {
  563. -      count = MIN(count,(mdrcnt-(44+50))/94); 
  564. -      count = MAX(count,0);
  565. -    }
  566.  
  567. -  *rparam_len = 6;
  568. +/****************************************************************************
  569. +  view list of all print jobs on all queues
  570. +  ****************************************************************************/
  571. +static BOOL api_DosPrintQEnum(int cnum, char* param, char* data,
  572. +                   int mdrcnt, int mprcnt,
  573. +                   char **rdata, char** rparam,
  574. +                   int *rdata_len, int *rparam_len)
  575. +{
  576. +  char *param_format = param+2;
  577. +  char *output_format1 = skip_string(param_format,1);
  578. +  char *p = skip_string(output_format1,1);
  579. +  int uLevel = SVAL(p,0);
  580. +  char *output_format2 = p + 4;
  581. +  int services = lp_numservices();
  582. +  int i, n;
  583. +  struct pack_desc desc;
  584. +  print_queue_struct **queue = NULL;
  585. +  print_status_struct *status = NULL;
  586. +  int* subcntarr = NULL;
  587. +  int queuecnt, subcnt=0, succnt;
  588. +  DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
  589. +  if (strcmp(param_format,"WrLeh") != 0) return False;
  590. +  if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
  591. +    return False;
  592. +  queuecnt = 0;
  593. +  for (i = 0; i < services; i++)
  594. +    if (lp_print_ok(i) && lp_browseable(i))
  595. +      queuecnt++;
  596. +  if (uLevel > 0) {
  597. +    queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*));
  598. +    memset(queue,0,queuecnt*sizeof(print_queue_struct*));
  599. +    status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct));
  600. +    memset(status,0,queuecnt*sizeof(print_status_struct));
  601. +    subcntarr = (int*)malloc(queuecnt*sizeof(int));
  602. +    subcnt = 0;
  603. +    n = 0;
  604. +    for (i = 0; i < services; i++)
  605. +      if (lp_print_ok(i) && lp_browseable(i)) {
  606. +     subcntarr[n] = get_printqueue(i,cnum,&queue[n],&status[n]);
  607. +     subcnt += subcntarr[n];
  608. +     n++;
  609. +      }
  610. +  }
  611. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  612. +  desc.base = *rdata;
  613. +  desc.buflen = mdrcnt;
  614. +  init_package(&desc,queuecnt,subcnt);
  615. +  n = 0;
  616. +  succnt = 0;
  617. +  for (i = 0; i < services; i++)
  618. +    if (lp_print_ok(i) && lp_browseable(i)) {
  619. +      fill_printq_info(cnum,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
  620. +      n++;
  621. +      if (desc.errcode == NERR_Success) succnt = n;
  622. +    }
  623. +  if (subcntarr) free(subcntarr);
  624. +  *rdata_len = desc.usedlen;
  625. +  *rparam_len = 8;
  626.    *rparam = REALLOC(*rparam,*rparam_len);
  627. +  SSVALS(*rparam,0,desc.errcode);
  628. +  SSVAL(*rparam,2,0);
  629. +  SSVAL(*rparam,4,succnt);
  630. +  SSVAL(*rparam,6,queuecnt);
  631. +  
  632. +  for (i = 0; i < queuecnt; i++) {
  633. +    if (queue && queue[i]) free(queue[i]);
  634. +  }
  635.  
  636. -  switch (uLevel)
  637. -    {
  638. -    case 0:
  639. -      *rdata_len = 13; 
  640. -      *rdata = REALLOC(*rdata,*rdata_len);
  641. -      p2 = (*rdata) + (*rdata_len);
  642. -      SSVALS(*rparam,0,NERR_Success); /* 0x84b */
  643. -      SSVAL(*rparam,2,0); 
  644. -      SSVAL(*rparam,4,13); 
  645. -      break;
  646. +  if (queue) free(queue);
  647. +  if (status) free(status);
  648. +  
  649. +  return True;
  650. +}
  651.  
  652. -    case 1:
  653. -      *rdata_len = 13 + 1 + 30; 
  654. -      *rdata = REALLOC(*rdata,*rdata_len + 100);
  655. -
  656. -      p2 = (*rdata) + 44;
  657. -
  658. -      SSVAL(*rparam,0,NERR_Success);
  659. -      SSVAL(*rparam,2,0); /* converter word */
  660. -      SSVAL(*rparam,4,*rdata_len); /* length of rdata struct */
  661. -      break;
  662. -    case 2:
  663. -      *rdata_len = 13 + 1 + 30; 
  664. -      *rdata = REALLOC(*rdata,*rdata_len + 100 + count*(74+40));
  665. -
  666. -      p2 = (*rdata) + 44 + count*74; /* auxillery data (strings) 
  667. -                    will go here */
  668. -
  669. -      SSVAL(*rparam,0,NERR_Success);
  670. -      SSVAL(*rparam,2,0); /* converter word */
  671. -      SSVAL(*rparam,4,*rdata_len); /* length of rdata struct */
  672. -      break;
  673. -    case 3:
  674. -      *rdata_len = 0; 
  675. -      p2 = (*rdata) + (*rdata_len);
  676. -      SSVALS(*rparam,0,0x7c);
  677. -      SSVAL(*rparam,2,0x70); 
  678. -      SSVAL(*rparam,4,0); 
  679. -      break;
  680. -    }
  681. +/****************************************************************************
  682. +  get info about a share
  683. +  ****************************************************************************/
  684.  
  685. -  p = *rdata;
  686. +static int check_share_info(int uLevel, const char* id)
  687. +{
  688. +  switch( uLevel ) {
  689. +  case 0:
  690. +    if (strcmp(id,"B13") != 0) return False;
  691. +    break;
  692. +  case 1:
  693. +    if (strcmp(id,"B13BWz") != 0) return False;
  694. +    break;
  695. +  case 2:
  696. +    if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
  697. +    break;
  698. +  case 91:
  699. +    if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
  700. +    break;
  701. +  default: return False;
  702. +  }
  703. +  return True;
  704. +}
  705.  
  706. -  if (uLevel <= 2)
  707. +static int fill_share_info(int cnum, int snum, int uLevel,
  708. +                char** buf, int* buflen,
  709. +                char** stringbuf, int* stringspace, char* baseaddr)
  710. +{
  711. +  int struct_len;
  712. +  char* p;
  713. +  char* p2;
  714. +  int l2;
  715. +  int len;
  716. +  switch( uLevel ) {
  717. +  case 0: struct_len = 13; break;
  718. +  case 1: struct_len = 20; break;
  719. +  case 2: struct_len = 40; break;
  720. +  case 91: struct_len = 68; break;
  721. +  default: return -1;
  722. +  }
  723. +  
  724. +  if (!buf)
  725.      {
  726. -      StrnCpy(p,QueueName,13);
  727. -      p += 13;
  728. +      len = 0;
  729. +      if (uLevel > 0) len += StrlenExpanded(cnum,snum,lp_comment(snum));
  730. +      if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
  731. +      if (buflen) *buflen = struct_len;
  732. +      if (stringspace) *stringspace = len;
  733. +      return struct_len + len;
  734.      }
  735. -
  736. -  if (uLevel == 2 || uLevel == 1)
  737. +  
  738. +  len = struct_len;
  739. +  p = *buf;
  740. +  if (*buflen < struct_len) return -1;
  741. +  if (stringbuf)
  742.      {
  743. -      p++; /* skip the pad byte */
  744. -      SSVAL(p,0,0); /* priority */
  745. -      SSVAL(p,2,0); /* start time */
  746. -      SSVAL(p,4,0); /* until time */
  747. -      SIVAL(p,6,0); /* pSepFile */
  748. -      SIVAL(p,10,0); /* pPrProc */
  749. -      SIVAL(p,14,0); /* pDestinations */
  750. -      SIVAL(p,18,0); /* pParms */
  751. -
  752. -      SIVAL(p,22,PTR_DIFF(p2,*rdata)); /* pComment */
  753. -      if (snum < 0) {
  754. -    strcpy(p2,"UNKNOWN PRINTER");
  755. -      } else {
  756. -    if (!status.message) {
  757. -      pstring comment;
  758. -      strcpy(comment,lp_comment(snum));
  759. -      string_sub(comment,"%S",lp_servicename(snum));
  760. -      standard_sub(cnum,comment);
  761. -      StrnCpy(p2,comment,40);
  762. -      SSVAL(p,26,LPSTAT_OK); /* status */
  763. -    } else {
  764. -      StrnCpy(p2,status.message,40);
  765. -      SSVAL(p,26,status.status); /* status */
  766. -    }
  767. -      }
  768. -
  769. -      p2 = skip_string(p2,1);
  770. -
  771. -      SSVAL(p,28,count); /* num jobs */
  772. -      p += 30;
  773. +      p2 = *stringbuf;
  774. +      l2 = *stringspace;
  775.      }
  776. -
  777. -  if (status.message) {
  778. -    free(status.message); 
  779. -    status.message = NULL;
  780. -  }
  781. -
  782. -  if (uLevel == 2)
  783. -  for (i=0;i<count;i++)
  784. +  else
  785.      {
  786. -      /* we encode the snum and job number in this way so we can extract
  787. -     then both for a print queue del operation */
  788. -      SSVAL(p,0,((snum%0xFF)<<8) | (queue[i].job%0xFF));
  789. -      StrnCpy(p+2,queue[i].user,21);
  790. -      StrnCpy(p+24,"",16); /* notify name */
  791. -      StrnCpy(p+40,"",10); /* data type */
  792. -      SIVAL(p,50,0); /* pParams */
  793. -      SSVAL(p,54,i); /* position */
  794. -      SSVAL(p,56,queue[i].status); /* status */
  795. -      SIVAL(p,58,0); /* pStatus string */
  796. -      SIVAL(p,62,queue[i].time); /* submit time */
  797. -      SIVAL(p,66,queue[i].size); /* job size */
  798. -
  799. -      SIVAL(p,70,PTR_DIFF(p2,*rdata));
  800. -      StrnCpy(p2,queue[i].file,39);
  801. -      p2 = skip_string(p2,1);      
  802. -
  803. -      p += 74;
  804. +      p2 = p + struct_len;
  805. +      l2 = *buflen - struct_len;
  806.      }
  807. -
  808. -  *rdata_len = PTR_DIFF(p2,*rdata);
  809. -
  810. -  if (queue) free(queue);
  811. +  if (!baseaddr) baseaddr = p;
  812. +  
  813. +  StrnCpy(p,lp_servicename(snum),13);
  814. +  
  815. +  if (uLevel > 0)
  816. +    {
  817. +      int type;
  818. +      CVAL(p,13) = 0;
  819. +      type = STYPE_DISKTREE;
  820. +      if (lp_print_ok(snum)) type = STYPE_PRINTQ;
  821. +      if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
  822. +      SSVAL(p,14,type);        /* device type */
  823. +      SIVAL(p,16,PTR_DIFF(p2,baseaddr));
  824. +      len += CopyExpanded(cnum,snum,&p2,lp_comment(snum),&l2);
  825. +    }
  826. +  
  827. +  if (uLevel > 1)
  828. +    {
  829. +      SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
  830. +      SSVAL(p,22,-1);        /* max uses */
  831. +      SSVAL(p,24,1); /* current uses */
  832. +      SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
  833. +      len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
  834. +      memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
  835. +    }
  836. +  
  837. +  if (uLevel > 2)
  838. +    {
  839. +      memset(p+40,0,SHPWLEN+2);
  840. +      SSVAL(p,50,0);
  841. +      SIVAL(p,52,0);
  842. +      SSVAL(p,56,0);
  843. +      SSVAL(p,58,0);
  844. +      SIVAL(p,60,0);
  845. +      SSVAL(p,64,0);
  846. +      SSVAL(p,66,0);
  847. +    }
  848. +       
  849. +  if (stringbuf)
  850. +    {
  851. +      *buf = p + struct_len;
  852. +      *buflen -= struct_len;
  853. +      *stringbuf = p2;
  854. +      *stringspace = l2;
  855. +    }
  856. +  else
  857. +    {
  858. +      *buf = p2;
  859. +      *buflen -= len;
  860. +    }
  861. +  return len;
  862. +}
  863.  
  864. -  DEBUG(3,("DosPrintQGetInfo on <%s> gave %d entries\n",QueueName,count));
  865. +static BOOL api_RNetShareGetInfo(int cnum,char *param,char *data,
  866. +                 int mdrcnt,int mprcnt,
  867. +                 char **rdata,char **rparam,
  868. +                 int *rdata_len,int *rparam_len)
  869. +{
  870. +  char *str1 = param+2;
  871. +  char *str2 = skip_string(str1,1);
  872. +  char *netname = skip_string(str2,1);
  873. +  char *p = skip_string(netname,1);
  874. +  int uLevel = SVAL(p,0);
  875. +  int snum = find_service(netname);
  876. +  
  877. +  if (snum < 0) return False;
  878. +  
  879. +  /* check it's a supported varient */
  880. +  if (strcmp(str1,"zWrLh") != 0) return False;
  881. +  if (!check_share_info(uLevel,str2)) return False;
  882. +  *rdata = REALLOC(*rdata,mdrcnt);
  883. +  p = *rdata;
  884. +  *rdata_len = fill_share_info(cnum,snum,uLevel,&p,&mdrcnt,0,0,0);
  885. +  if (*rdata_len < 0) return False;
  886. +  *rparam_len = 6;
  887. +  *rparam = REALLOC(*rparam,*rparam_len);
  888. +  SSVAL(*rparam,0,NERR_Success);
  889. +  SSVAL(*rparam,2,0);        /* converter word */
  890. +  SSVAL(*rparam,4,*rdata_len);
  891.    return(True);
  892.  }
  893.  
  894. -
  895.  /****************************************************************************
  896. -view list of shares available
  897. -expect: WrLeh  B13BWz
  898. -
  899. -NOTE:  SEGV has been reported inside this routine. It needs to be investigated.
  900. -****************************************************************************/
  901. +  view list of shares available
  902. +  ****************************************************************************/
  903.  static BOOL api_RNetShareEnum(int cnum,char *param,char *data,
  904. -                  int mdrcnt,int mprcnt,
  905. -                  char **rdata,char **rparam,
  906. -                  int *rdata_len,int *rparam_len)
  907. +                    int mdrcnt,int mprcnt,
  908. +                    char **rdata,char **rparam,
  909. +                    int *rdata_len,int *rparam_len)
  910.  {
  911. -  char *p = skip_string(param+2,2);
  912. -  int level = SVAL(p,0);
  913. +  char *str1 = param+2;
  914. +  char *str2 = skip_string(str1,1);
  915. +  char *p = skip_string(str2,1);
  916. +  int uLevel = SVAL(p,0);
  917.    int buf_len = SVAL(p,2);
  918.    char *p2;
  919.    int count=lp_numservices();
  920.    int total=0,counted=0;
  921. -  int comment_len=0;
  922.    int i;
  923. -  BOOL squeezed = False;
  924. -
  925. +  int data_len, fixed_len, string_len;
  926. +  int f_len, s_len;
  927. +  if (strcmp(str1,"WrLeh") != 0) return False;
  928. +  if (!check_share_info(uLevel,str2)) return False;
  929. +  
  930. +  data_len = fixed_len = string_len = 0;
  931.    for (i=0;i<count;i++)
  932.      if (lp_browseable(i))
  933.        {
  934. -    pstring s;
  935. -    strcpy(s,lp_comment(i));
  936. -    string_sub(s,"%S",lp_servicename(i));
  937. -    standard_sub(cnum,s);
  938. -    total++;
  939. -    comment_len += strlen(s) + 1;
  940. +      total++;
  941. +     data_len += fill_share_info(cnum,i,uLevel,0,&f_len,0,&s_len,0);
  942. +     if (data_len <= buf_len)
  943. +       {
  944. +         counted++;
  945. +         fixed_len += f_len;
  946. +         string_len += s_len;
  947. +       }
  948.        }
  949. -
  950. -  *rparam_len = 8;
  951. -  *rparam = REALLOC(*rparam,*rparam_len);
  952. -
  953. -  *rdata_len = total*20 + comment_len;
  954. +  *rdata_len = fixed_len + string_len;
  955.    *rdata = REALLOC(*rdata,*rdata_len);
  956. -  bzero(*rdata,*rdata_len);
  957. -
  958. -  total = MIN(total,buf_len/25);
  959. -
  960. -  p2 = (*rdata) + total*20; /* auxillery data (strings) will go here */
  961. -
  962. +  memset(*rdata,0,*rdata_len);
  963. +  
  964. +  p2 = (*rdata) + fixed_len;    /* auxillery data (strings) will go here */
  965.    p = *rdata;
  966. -
  967. -  for (i=0;i<count && counted<total;i++)
  968. +  f_len = fixed_len;
  969. +  s_len = string_len;
  970. +  for (i = 0; i < count;i++)
  971.      if (lp_browseable(i))
  972. -      {
  973. -    int type = 0;
  974. -
  975. -    if (lp_print_ok(i)) type = 1;
  976. -    if (strequal("IPC$",lp_servicename(i))) type = 3;
  977. -
  978. -    StrnCpy(p,lp_servicename(i),12);
  979. -    CVAL(p,13) = 0; /* pad */
  980. -    SSVAL(p,14,type); /* device type */
  981. -    SIVAL(p,16,PTR_DIFF(p2,(*rdata)));
  982. -    strcpy(p2,lp_comment(i));
  983. -    string_sub(p2,"%S",lp_servicename(i));
  984. -    standard_sub(cnum,p2);
  985. -
  986. -    if (!squeezed &&
  987. -        PTR_DIFF(skip_string(p2,1),*rdata) < (buf_len-2))
  988. -      p2 = skip_string(p2,1);
  989. -    else
  990. -      squeezed = True;
  991. -
  992. -    p += 20;
  993. -    counted++;
  994. -      }
  995. -
  996. -
  997. -  if (squeezed)
  998. -    {
  999. -      strcpy(p2,"-");
  1000. -      p2 += 2;
  1001. -    }
  1002. -
  1003. -  if (counted < total)
  1004. -    {
  1005. -      memmove((*rdata) + counted*20,(*rdata) + total*20,
  1006. -          PTR_DIFF(p2,(*rdata) + total*20)+2);
  1007. -      p2 -= (total-counted)*20;      
  1008. -    }
  1009. -
  1010. -  *rdata_len = PTR_DIFF(p2,(*rdata));
  1011. -
  1012. +      if (fill_share_info(cnum,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
  1013. +     break;
  1014. +  
  1015. +  *rparam_len = 8;
  1016. +  *rparam = REALLOC(*rparam,*rparam_len);
  1017.    SSVAL(*rparam,0,NERR_Success);
  1018. -  SSVAL(*rparam,2,(total-counted)*20); /* converter word */
  1019. +  SSVAL(*rparam,2,0);
  1020.    SSVAL(*rparam,4,counted);
  1021.    SSVAL(*rparam,6,total);
  1022. -
  1023. +  
  1024.    DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
  1025. -       counted,total,level,
  1026. -       buf_len,*rdata_len,mdrcnt));
  1027. +        counted,total,uLevel,
  1028. +         buf_len,*rdata_len,mdrcnt));
  1029.    return(True);
  1030.  }
  1031.  
  1032.  
  1033.  
  1034.  /****************************************************************************
  1035. -get the time of day info
  1036. -****************************************************************************/
  1037. +  get the time of day info
  1038. +  ****************************************************************************/
  1039.  static BOOL api_NetRemoteTOD(int cnum,char *param,char *data,
  1040.                   int mdrcnt,int mprcnt,
  1041.                   char **rdata,char **rparam,
  1042. @@ -417,7 +876,7 @@
  1043.    *rdata = REALLOC(*rdata,*rdata_len);
  1044.  
  1045.    SSVAL(*rparam,0,NERR_Success);
  1046. -  SSVAL(*rparam,2,0); /* converter word */
  1047. +  SSVAL(*rparam,2,0);        /* converter word */
  1048.  
  1049.    p = *rdata;
  1050.  
  1051. @@ -428,16 +887,16 @@
  1052.      t = LocalTime(&unixdate,0);
  1053.  
  1054.      SIVAL(p,0,unixdate); 
  1055. -    SIVAL(p,4,0); /* msecs ? */
  1056. +    SIVAL(p,4,0);        /* msecs ? */
  1057.      CVAL(p,8) = t->tm_hour;
  1058.      CVAL(p,9) = t->tm_min;
  1059.      CVAL(p,10) = t->tm_sec;
  1060. -    CVAL(p,11) = 0; /* hundredths of seconds */
  1061. +    CVAL(p,11) = 0;        /* hundredths of seconds */
  1062.      SSVAL(p,12,TimeDiff(0)/60); /* timezone in minutes from GMT */
  1063. -    SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
  1064. +    SSVAL(p,14,10000);        /* timer interval in 0.0001 of sec */
  1065.      CVAL(p,16) = t->tm_mday;
  1066.      CVAL(p,17) = t->tm_mon + 1;
  1067. -    SSVAL(p,18,t->tm_year);
  1068. +    SSVAL(p,18,1900+t->tm_year);
  1069.      CVAL(p,20) = t->tm_wday;
  1070.    }
  1071.  
  1072. @@ -446,8 +905,8 @@
  1073.  }
  1074.  
  1075.  /****************************************************************************
  1076. -set the user password
  1077. -****************************************************************************/
  1078. +  set the user password
  1079. +  ****************************************************************************/
  1080.  static BOOL api_SetUserPassword(int cnum,char *param,char *data,
  1081.                  int mdrcnt,int mprcnt,
  1082.                  char **rdata,char **rparam,
  1083. @@ -468,7 +927,7 @@
  1084.    *rdata_len = 0;
  1085.  
  1086.    SSVAL(*rparam,0,NERR_Success);
  1087. -  SSVAL(*rparam,2,0); /* converter word */
  1088. +  SSVAL(*rparam,2,0);        /* converter word */
  1089.  
  1090.    DEBUG(3,("Set password for <%s>\n",user));
  1091.  
  1092. @@ -482,9 +941,9 @@
  1093.  }
  1094.  
  1095.  /****************************************************************************
  1096. -delete a print job
  1097. -Form: <W> <> 
  1098. -****************************************************************************/
  1099. +  delete a print job
  1100. +  Form: <W> <> 
  1101. +  ****************************************************************************/
  1102.  static BOOL api_RDosPrintJobDel(int cnum,char *param,char *data,
  1103.                  int mdrcnt,int mprcnt,
  1104.                  char **rdata,char **rparam,
  1105. @@ -497,6 +956,7 @@
  1106.                     by the print queue api */
  1107.    int snum = (SVAL(p,0)>>8);  
  1108.  
  1109. +  lpq_cache_reset = True;
  1110.  
  1111.    /* check it's a supported varient */
  1112.    if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
  1113. @@ -508,7 +968,7 @@
  1114.    *rdata_len = 0;
  1115.  
  1116.    SSVAL(*rparam,0,NERR_Success);
  1117. -  SSVAL(*rparam,2,0); /* converter word */
  1118. +  SSVAL(*rparam,2,0);        /* converter word */
  1119.  
  1120.    if (snum >= 0)
  1121.      {
  1122. @@ -531,9 +991,59 @@
  1123.    return(True);
  1124.  }
  1125.  
  1126. +static BOOL api_WPrintQueuePurge(int cnum,char *param,char *data,
  1127. +                 int mdrcnt,int mprcnt,
  1128. +                 char **rdata,char **rparam,
  1129. +                 int *rdata_len,int *rparam_len)
  1130. +{
  1131. +  char *str1 = param+2;
  1132. +  char *str2 = skip_string(str1,1);
  1133. +  char *QueueName = skip_string(str2,1);
  1134. +  int snum;
  1135. +
  1136. +  lpq_cache_reset = True;
  1137. +
  1138. +  /* check it's a supported varient */
  1139. +  if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
  1140. +    return(False);
  1141. +
  1142. +  *rparam_len = 4;
  1143. +  *rparam = REALLOC(*rparam,*rparam_len);
  1144. +
  1145. +  *rdata_len = 0;
  1146. +
  1147. +  SSVAL(*rparam,0,NERR_Success);
  1148. +  SSVAL(*rparam,2,0);        /* converter word */
  1149. +
  1150. +  snum = lp_servicenumber(QueueName);
  1151. +  if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
  1152. +    int pnum = lp_servicenumber(PRINTERS_NAME);
  1153. +    if (pnum >= 0) {
  1154. +      lp_add_printer(QueueName,pnum);
  1155. +      snum = lp_servicenumber(QueueName);
  1156. +    }
  1157. +  }
  1158. +
  1159. +  if (snum >= 0) {
  1160. +    print_queue_struct *queue=NULL;
  1161. +    int i;
  1162. +    int count = get_printqueue(snum,cnum,&queue,NULL);
  1163. +
  1164. +    for (i = 0; i < count; i++)
  1165. +      del_printqueue(cnum,snum,queue[i].job);
  1166. +
  1167. +    if (queue) free(queue);
  1168. +  }
  1169. +
  1170. +  DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
  1171. +
  1172. +  return(True);
  1173. +}
  1174. +
  1175. +
  1176.  /****************************************************************************
  1177. -set the name of a print job (undocumented?)
  1178. -****************************************************************************/
  1179. +  set the name of a print job (undocumented?)
  1180. +  ****************************************************************************/
  1181.  static BOOL api_PrintJobInfo(int cnum,char *param,char *data,
  1182.                   int mdrcnt,int mprcnt,
  1183.                   char **rdata,char **rparam,
  1184. @@ -544,10 +1054,12 @@
  1185.    *rparam_len = 4;
  1186.    *rparam = REALLOC(*rparam,*rparam_len);
  1187.  
  1188. +  lpq_cache_reset = True;
  1189. +
  1190.    *rdata_len = 0;
  1191.  
  1192.    SSVAL(*rparam,0,NERR_Success);
  1193. -  SSVAL(*rparam,2,0); /* converter word */
  1194. +  SSVAL(*rparam,2,0);        /* converter word */
  1195.  
  1196.    /* now try to extract the name. As I don't really understand this
  1197.       API this is mostly guesswork.
  1198. @@ -586,8 +1098,18 @@
  1199.  
  1200.  
  1201.  /****************************************************************************
  1202. -get info about the server (no docs on this one - guesswork only)
  1203. -****************************************************************************/
  1204. +  get info about the server
  1205. +  ****************************************************************************/
  1206. +
  1207. +#define SV_TYPE_WORKSTATION    0x00000001
  1208. +#define SV_TYPE_SERVER        0x00000002
  1209. +#define SV_TYPE_SQLSERVER    0x00000004
  1210. +#define SV_TYPE_DOMAIN_CTRL    0x00000008
  1211. +#define SV_TYPE_DOMAIN_BAKCTRL    0x00000010
  1212. +#define SV_TYPE_TIME_SOURCE    0x00000020
  1213. +#define SV_TYPE_AFP        0x00000040
  1214. +#define SV_TYPE_NOVELL        0x00000080
  1215. +
  1216.  static BOOL api_RNetServerGetInfo(int cnum,char *param,char *data,
  1217.                    int mdrcnt,int mprcnt,
  1218.                    char **rdata,char **rparam,
  1219. @@ -596,71 +1118,82 @@
  1220.    char *str1 = param+2;
  1221.    char *str2 = skip_string(str1,1);
  1222.    char *p = skip_string(str2,1);
  1223. +  int uLevel = SVAL(p,0);
  1224.    char *p2;
  1225. -  pstring comment;
  1226. -  int level = SVAL(p,0);
  1227. -
  1228. -  DEBUG(4,("RNetServerGetInfo level %d\n",level));
  1229. -
  1230. -  *rparam_len = 6;
  1231. -  *rparam = REALLOC(*rparam,*rparam_len);
  1232. +  int struct_len;
  1233.  
  1234.    /* check it's a supported varient */
  1235. -  if (!(
  1236. -    (level==1 && strcsequal(str1,"WrLh") && strcsequal(str2,"B16BBDz")) ||
  1237. -    (level==50 && strcsequal(str1,"WrLh") && strcsequal(str2,"B16BBDzWWzzz"))
  1238. -    ))
  1239. -    return(False);
  1240. -
  1241. -  strcpy(comment,lp_serverstring());
  1242. -  standard_sub(cnum,comment);
  1243. +  if (strcmp(str1,"WrLh") != 0) return False;
  1244. +  switch( uLevel ) {
  1245. +  case 0:
  1246. +    if (strcmp(str2,"B16") != 0) return False;
  1247. +    struct_len = 16;
  1248. +    break;
  1249. +  case 1:
  1250. +    if (strcmp(str2,"B16BBDz") != 0) return False;
  1251. +    struct_len = 26;
  1252. +    break;
  1253. +  case 2:
  1254. +    if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
  1255. +    != 0) return False;
  1256. +    struct_len = 134;
  1257. +    break;
  1258. +  case 3:
  1259. +    if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
  1260. +    != 0) return False;
  1261. +    struct_len = 144;
  1262. +    break;
  1263. +  case 20:
  1264. +    if (strcmp(str2,"DN") != 0) return False;
  1265. +    struct_len = 6;
  1266. +    break;
  1267. +  case 50:
  1268. +    if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
  1269. +    struct_len = 42;
  1270. +    break;
  1271. +  default: return False;
  1272. +  }
  1273.  
  1274.    *rdata_len = mdrcnt;
  1275.    *rdata = REALLOC(*rdata,*rdata_len);
  1276.  
  1277. -  SSVAL(*rparam,0,NERR_Success);
  1278. -  SSVAL(*rparam,2,0); /* converter word */
  1279. -
  1280.    p = *rdata;
  1281. -  p2 = p + 42;
  1282. -
  1283. -  StrnCpy(p,local_machine,16);
  1284. +  p2 = p + struct_len;
  1285. +  if (uLevel != 20) StrnCpy(p,local_machine,16);
  1286.    p += 16;
  1287. -  p += 2;
  1288. -  SIVAL(p,0,0xB03); /* unix server */
  1289. -  p += 4;
  1290. +  if (uLevel > 0)
  1291. +    {
  1292. +      pstring comment;
  1293. +      SCVAL(p,0,1);        /* version_major */
  1294. +      SCVAL(p,1,9);        /* version_minor */
  1295. +      SIVAL(p,2,SV_TYPE_WORKSTATION|SV_TYPE_SERVER|SV_TYPE_TIME_SOURCE
  1296. +        /*|SV_TYPE_DOMAIN_CTRL*/); /* type */
  1297. +      SIVAL(p,6,PTR_DIFF(p2,*rdata));
  1298. +      strcpy(comment,lp_serverstring());
  1299. +      standard_sub(cnum,comment);
  1300. +      StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
  1301. +      p2 = skip_string(p2,1);
  1302. +    }
  1303. +  if (uLevel > 1)
  1304. +    {
  1305. +      return False;        /* not yet implemented */
  1306. +    }
  1307.  
  1308. -  SIVAL(p,0,PTR_DIFF(p2,*rdata)); p+=4;
  1309. -  strcpy(p2,comment);
  1310. -  p2 = skip_string(p2,1);      
  1311. -
  1312. -  if (strcsequal(str2,"B16BBDzWWzzz")) {
  1313. -    p += 4;
  1314. -
  1315. -    SIVAL(p,0,PTR_DIFF(p2,*rdata)); p+=4;
  1316. -    strcpy(p2,"str 1");
  1317. -    p2 = skip_string(p2,1);      
  1318. -
  1319. -    SIVAL(p,0,PTR_DIFF(p2,*rdata)); p+=4;
  1320. -    strcpy(p2,"str 2");
  1321. -    p2 = skip_string(p2,1);      
  1322. -    
  1323. -    SIVAL(p,0,PTR_DIFF(p2,*rdata)); p+=4;
  1324. -    strcpy(p2,"str 3");
  1325. -    p2 = skip_string(p2,1);      
  1326. -  }
  1327. -  
  1328.    *rdata_len = PTR_DIFF(p2,*rdata);
  1329.  
  1330. -  SSVAL(*rparam,4,*rdata_len); /* is this right? */
  1331. +  *rparam_len = 6;
  1332. +  *rparam = REALLOC(*rparam,*rparam_len);
  1333. +  SSVAL(*rparam,0,NERR_Success);
  1334. +  SSVAL(*rparam,2,0);        /* converter word */
  1335. +  SSVAL(*rparam,4,*rdata_len);
  1336.  
  1337.    return(True);
  1338.  }
  1339.  
  1340.  
  1341.  /****************************************************************************
  1342. -get info about the server
  1343. -****************************************************************************/
  1344. +  get info about the server
  1345. +  ****************************************************************************/
  1346.  static BOOL api_NetWkstaGetInfo(int cnum,char *param,char *data,
  1347.                  int mdrcnt,int mprcnt,
  1348.                  char **rdata,char **rparam,
  1349. @@ -686,7 +1219,7 @@
  1350.    *rdata = REALLOC(*rdata,*rdata_len);
  1351.  
  1352.    SSVAL(*rparam,0,NERR_Success);
  1353. -  SSVAL(*rparam,2,0); /* converter word */
  1354. +  SSVAL(*rparam,2,0);        /* converter word */
  1355.  
  1356.    p = *rdata;
  1357.    p2 = p + 22;
  1358. @@ -711,7 +1244,7 @@
  1359.    p += 2;
  1360.  
  1361.    SIVAL(p,0,PTR_DIFF(p2,*rdata));
  1362. -  strcpy(p2,lp_workgroup()); /* login domain */
  1363. +  strcpy(p2,lp_workgroup());    /* login domain */
  1364.    p2 = skip_string(p2,1);
  1365.    p += 4;
  1366.  
  1367. @@ -728,10 +1261,649 @@
  1368.  }
  1369.  
  1370.  
  1371. +/****************************************************************************
  1372. +  get info about a user
  1373. +  ****************************************************************************/
  1374. +
  1375. +#define USER_PRIV_GUEST 0
  1376. +#define USER_PRIV_USER 1
  1377. +#define USER_PRIV_ADMIN 2
  1378. +
  1379. +static BOOL api_RNetUserGetInfo(int cnum,char *param,char *data,
  1380. +                int mdrcnt,int mprcnt,
  1381. +                char **rdata,char **rparam,
  1382. +                int *rdata_len,int *rparam_len)
  1383. +{
  1384. +  char *str1 = param+2;
  1385. +  char *str2 = skip_string(str1,1);
  1386. +  char *UserName = skip_string(str2,1);
  1387. +  char *p = skip_string(UserName,1);
  1388. +  int uLevel = SVAL(p,0);
  1389. +  char *p2;
  1390. +
  1391. +  *rparam_len = 6;
  1392. +  *rparam = REALLOC(*rparam,*rparam_len);
  1393. +
  1394. +  /* check it's a supported varient */
  1395. +  if (strcmp(str1,"zWrLh") != 0) return False;
  1396. +  switch( uLevel ) {
  1397. +  case 0: p2 = "B21"; break;
  1398. +  case 1: p2 = "B21BB16DWzzWz"; break;
  1399. +  case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
  1400. +  case 10: p2 = "B21Bzzz"; break;
  1401. +  case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
  1402. +  default: return False;
  1403. +  }
  1404. +  if (strcmp(p2,str2) != 0) return False;
  1405. +
  1406. +  *rdata_len = mdrcnt + 1024;
  1407. +  *rdata = REALLOC(*rdata,*rdata_len);
  1408. +
  1409. +  SSVAL(*rparam,0,NERR_Success);
  1410. +  SSVAL(*rparam,2,0);        /* converter word */
  1411. +
  1412. +  p = *rdata;
  1413. +  p2 = p + 86;
  1414. +
  1415. +  memset(p,0,21);
  1416. +  strcpy(p,UserName);
  1417. +  if (uLevel > 0) {
  1418. +    SCVAL(p,21,0);
  1419. +    *p2 = 0;
  1420. +    if (uLevel >= 10) {
  1421. +      SIVAL(p,22,PTR_DIFF(p2,*rdata)); /* comment */
  1422. +      SIVAL(p,26,PTR_DIFF(p2,*rdata)); /* user_comment */
  1423. +      SIVAL(p,30,PTR_DIFF(p2,*rdata)); /* full name */
  1424. +      p2++;
  1425. +    }
  1426. +    if (uLevel == 11) {
  1427. +      SSVAL(p,34,USER_PRIV_ADMIN); /* user privilege */
  1428. +      SIVAL(p,36,0);        /* auth flags */
  1429. +      SIVAL(p,40,0);        /* password age */
  1430. +      SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
  1431. +      strcpy(p2,"Y:\\GIGA\\C$\\PRJ\\USERS\\AD");
  1432. +      p2 = skip_string(p2,1);
  1433. +      SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* parms */
  1434. +      strcpy(p2,"");
  1435. +      p2 = skip_string(p2,1);
  1436. +      SIVAL(p,52,0);        /* last logon */
  1437. +      SIVAL(p,56,0);        /* last logoff */
  1438. +      SSVAL(p,60,-1);        /* bad pw counts */
  1439. +      SSVAL(p,62,-1);        /* num logons */
  1440. +      SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* logon server */
  1441. +      strcpy(p2,"\\\\GIGA");
  1442. +      p2 = skip_string(p2,1);
  1443. +      SSVAL(p,68,49);        /* country code */
  1444. +      SIVAL(p,70,0);        /* workstations */
  1445. +
  1446. +      SIVAL(p,74,-1L);        /* max storage */
  1447. +      SSVAL(p,78,168);        /* units per week */
  1448. +      SIVAL(p,80,PTR_DIFF(p2,*rdata)); /* logon hours */
  1449. +      memset(p2,-1,21);
  1450. +      p2 += 21;
  1451. +      SSVAL(p,84,860);        /* code page */
  1452. +    }
  1453. +    if (uLevel == 1 || uLevel == 2) {
  1454. +      memset(p+22,' ',16);    /* password */
  1455. +      SIVAL(p,38,-1);        /* password age */
  1456. +      SSVAL(p,42,USER_PRIV_ADMIN); /* user privilege */
  1457. +      SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
  1458. +      strcpy(p2,"Y:\\GIGA\\C$\\PRJ\\USERS\\AD");
  1459. +      p2 = skip_string(p2,1);
  1460. +      SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
  1461. +      *p2++ = 0;
  1462. +      SSVAL(p,52,0);        /* flags */
  1463. +      SIVAL(p,54,0);        /* script_path */
  1464. +      if (uLevel == 2) {
  1465. +    SIVAL(p,60,0);        /* auth_flags */
  1466. +    SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
  1467. +    strcpy(p2,"<Full Name>");
  1468. +    p2 = skip_string(p2,1);
  1469. +    SIVAL(p,68,0);        /* urs_comment */
  1470. +    SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
  1471. +    strcpy(p2,"");
  1472. +    p2 = skip_string(p2,1);
  1473. +    SIVAL(p,76,0);        /* workstations */
  1474. +    SIVAL(p,80,0);        /* last_logon */
  1475. +    SIVAL(p,84,0);        /* last_logoff */
  1476. +    SIVAL(p,88,-1);        /* acct_expires */
  1477. +    SIVAL(p,92,-1);        /* max_storage */
  1478. +    SSVAL(p,96,168);    /* units_per_week */
  1479. +    SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
  1480. +    memset(p2,-1,21);
  1481. +    p2 += 21;
  1482. +    SSVAL(p,102,-1);    /* bad_pw_count */
  1483. +    SSVAL(p,104,-1);    /* num_logons */
  1484. +    SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
  1485. +    strcpy(p2,"\\\\GIGA");
  1486. +    p2 = skip_string(p2,1);
  1487. +    SSVAL(p,110,49);    /* country_code */
  1488. +    SSVAL(p,112,860);    /* code page */
  1489. +      }
  1490. +    }
  1491. +  }
  1492. +
  1493. +  *rdata_len = PTR_DIFF(p2,*rdata);
  1494. +
  1495. +  SSVAL(*rparam,4,*rdata_len);    /* is this right?? */
  1496. +
  1497. +  return(True);
  1498. +}
  1499. +
  1500. +static BOOL api_WWkstaUserLogon(int cnum,char *param,char *data,
  1501. +                int mdrcnt,int mprcnt,
  1502. +                char **rdata,char **rparam,
  1503. +                int *rdata_len,int *rparam_len)
  1504. +{
  1505. +  char *str1 = param+2;
  1506. +  char *str2 = skip_string(str1,1);
  1507. +  char *p = skip_string(str2,1);
  1508. +  int uLevel,cbBuf;
  1509. +  struct pack_desc desc;
  1510. +  char* name;
  1511. +
  1512. +  uLevel = SVAL(p,0);
  1513. +  cbBuf = SVAL(p,2);
  1514. +  name = p + 4;
  1515. +
  1516. +  DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
  1517. +
  1518. +  /* check it's a supported varient */
  1519. +  if (strcmp(str1,"OOWb54WrLh") != 0) return False;
  1520. +  if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
  1521. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1522. +  desc.base = *rdata;
  1523. +  desc.buflen = mdrcnt;
  1524. +  desc.subformat = NULL;
  1525. +  desc.format = str2;
  1526. +  init_package(&desc,1,0);
  1527. +  PACK(&desc,"W",0);        /* code */
  1528. +  PACK(&desc,"B21",name);    /* eff. name */
  1529. +  PACK(&desc,"B",0);        /* pad */
  1530. +  PACK(&desc,"W",2);        /* priv */
  1531. +  PACK(&desc,"D",0);        /* auth flags */
  1532. +  PACK(&desc,"W",0);        /* num logons */
  1533. +  PACK(&desc,"W",0);        /* bad pw count */
  1534. +  PACK(&desc,"D",0);        /* last logon */
  1535. +  PACK(&desc,"D",0);        /* last logoff */
  1536. +  PACK(&desc,"D",-1);        /* logoff time */
  1537. +  PACK(&desc,"D",-1);        /* kickoff time */
  1538. +  PACK(&desc,"D",0);        /* password age */
  1539. +  PACK(&desc,"D",0);        /* password can change */
  1540. +  PACK(&desc,"D",-1);        /* password must change */
  1541. +  PACK(&desc,"z",local_machine);/* computer */
  1542. +  PACK(&desc,"z",lp_workgroup());/* domain */
  1543. +  PACK(&desc,"z",0);        /* script path */
  1544. +  PACK(&desc,"D",0);        /* reserved */
  1545. +  *rdata_len = desc.usedlen;
  1546. +
  1547. +  *rparam_len = 6;
  1548. +  *rparam = REALLOC(*rparam,*rparam_len);
  1549. +  SSVALS(*rparam,0,desc.errcode);
  1550. +  SSVAL(*rparam,2,0);
  1551. +  SSVAL(*rparam,4,desc.neededlen);
  1552. +
  1553. +  DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
  1554. +  return(True);
  1555. +}
  1556. +
  1557. +
  1558. +/****************************************************************************
  1559. +  api_WAccessGetUserPerms
  1560. +  ****************************************************************************/
  1561. +static BOOL api_WAccessGetUserPerms(int cnum,char *param,char *data,
  1562. +                    int mdrcnt,int mprcnt,
  1563. +                    char **rdata,char **rparam,
  1564. +                    int *rdata_len,int *rparam_len)
  1565. +{
  1566. +  char *str1 = param+2;
  1567. +  char *str2 = skip_string(str1,1);
  1568. +  char *user = skip_string(str2,1);
  1569. +  char *resource = skip_string(user,1);
  1570. +
  1571. +  DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
  1572. +
  1573. +  /* check it's a supported varient */
  1574. +  if (strcmp(str1,"zzh") != 0) return False;
  1575. +  if (strcmp(str2,"") != 0) return False;
  1576. +
  1577. +  *rparam_len = 6;
  1578. +  *rparam = REALLOC(*rparam,*rparam_len);
  1579. +  SSVALS(*rparam,0,0);        /* errorcode */
  1580. +  SSVAL(*rparam,2,0);        /* converter word */
  1581. +  SSVAL(*rparam,4,0x7f);    /* permission flags */
  1582. +
  1583. +  return(True);
  1584. +}
  1585. +
  1586. +/****************************************************************************
  1587. +  api_WPrintJobEnumerate
  1588. +  ****************************************************************************/
  1589. +
  1590. +static int check_printjob_info(struct pack_desc* desc,
  1591. +                   int uLevel, const char* id)
  1592. +{
  1593. +  desc->subformat = NULL;
  1594. +  switch( uLevel ) {
  1595. +  case 0: desc->format = "W"; break;
  1596. +  case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
  1597. +  case 2: desc->format = "WWzWWDDzz"; break;
  1598. +  case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
  1599. +  default: return False;
  1600. +  }
  1601. +  if (strcmp(desc->format,id) != 0) return False;
  1602. +  return True;
  1603. +}
  1604. +
  1605. +static BOOL api_WPrintJobGetInfo(int cnum,char *param,char *data,
  1606. +                 int mdrcnt,int mprcnt,
  1607. +                 char **rdata,char **rparam,
  1608. +                 int *rdata_len,int *rparam_len)
  1609. +{
  1610. +  char *str1 = param+2;
  1611. +  char *str2 = skip_string(str1,1);
  1612. +  char *p = skip_string(str2,1);
  1613. +  int uJobId = SVAL(p,0);
  1614. +  int uLevel,cbBuf;
  1615. +  int count;
  1616. +  int i;
  1617. +  int snum;
  1618. +  int job;
  1619. +  struct pack_desc desc;
  1620. +  print_queue_struct *queue=NULL;
  1621. +  print_status_struct status;
  1622. +
  1623. +  uLevel = SVAL(p,2);
  1624. +  cbBuf = SVAL(p,4);
  1625. +
  1626. +  DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,uJobId));
  1627. +
  1628. +  /* check it's a supported varient */
  1629. +  if (strcmp(str1,"WWrLh") != 0) return False;
  1630. +  if (!check_printjob_info(&desc,uLevel,str2)) return False;
  1631. +
  1632. +  snum = (unsigned int)uJobId >> 8; /*## valid serice number??*/
  1633. +  job = uJobId & 0xFF;
  1634. +
  1635. +  count = get_printqueue(snum,cnum,&queue,&status);
  1636. +  for (i = 0; i < count; i++) {
  1637. +    if ((queue[i].job % 0xFF) == job) break;
  1638. +  }
  1639. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1640. +  desc.base = *rdata;
  1641. +  desc.buflen = mdrcnt;
  1642. +  init_package(&desc,1,0);
  1643. +  if (i < count) {
  1644. +    fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
  1645. +    *rdata_len = desc.usedlen;
  1646. +  }
  1647. +  else {
  1648. +    desc.errcode = NERR_JobNotFound;
  1649. +    *rdata_len = 0;
  1650. +  }
  1651. +
  1652. +  *rparam_len = 6;
  1653. +  *rparam = REALLOC(*rparam,*rparam_len);
  1654. +  SSVALS(*rparam,0,desc.errcode);
  1655. +  SSVAL(*rparam,2,0);
  1656. +  SSVAL(*rparam,4,desc.neededlen);
  1657. +
  1658. +  if (queue) free(queue);
  1659. +
  1660. +  DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
  1661. +  return(True);
  1662. +}
  1663. +
  1664. +static BOOL api_WPrintJobEnumerate(int cnum,char *param,char *data,
  1665. +                   int mdrcnt,int mprcnt,
  1666. +                   char **rdata,char **rparam,
  1667. +                   int *rdata_len,int *rparam_len)
  1668. +{
  1669. +  char *str1 = param+2;
  1670. +  char *str2 = skip_string(str1,1);
  1671. +  char *p = skip_string(str2,1);
  1672. +  char* name = p;
  1673. +  int uLevel,cbBuf;
  1674. +  int count;
  1675. +  int i, succnt;
  1676. +  int snum;
  1677. +  struct pack_desc desc;
  1678. +  print_queue_struct *queue=NULL;
  1679. +  print_status_struct status;
  1680. +
  1681. +  p = skip_string(p,1);
  1682. +  uLevel = SVAL(p,0);
  1683. +  cbBuf = SVAL(p,2);
  1684. +
  1685. +  DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
  1686. +
  1687. +  /* check it's a supported varient */
  1688. +  if (strcmp(str1,"zWrLeh") != 0) return False;
  1689. +  if (uLevel > 2) return False;    /* defined only for uLevel 0,1,2 */
  1690. +  if (!check_printjob_info(&desc,uLevel,str2)) return False;
  1691. +
  1692. +  snum = lp_servicenumber(name);
  1693. +  if (snum < 0 && pcap_printername_ok(name,NULL)) {
  1694. +    int pnum = lp_servicenumber(PRINTERS_NAME);
  1695. +    if (pnum >= 0) {
  1696. +      lp_add_printer(name,pnum);
  1697. +      snum = lp_servicenumber(name);
  1698. +    }
  1699. +  }
  1700. +
  1701. +  count = get_printqueue(snum,cnum,&queue,&status);
  1702. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1703. +  desc.base = *rdata;
  1704. +  desc.buflen = mdrcnt;
  1705. +  init_package(&desc,count,0);
  1706. +
  1707. +  succnt = 0;
  1708. +  for (i = 0; i < count; i++) {
  1709. +    fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
  1710. +    if (desc.errcode == NERR_Success) succnt = i+1;
  1711. +  }
  1712. +  *rdata_len = desc.usedlen;
  1713. +
  1714. +  *rparam_len = 8;
  1715. +  *rparam = REALLOC(*rparam,*rparam_len);
  1716. +  SSVALS(*rparam,0,desc.errcode);
  1717. +  SSVAL(*rparam,2,0);
  1718. +  SSVAL(*rparam,4,succnt);
  1719. +  SSVAL(*rparam,6,count);
  1720. +
  1721. +  if (queue) free(queue);
  1722. +
  1723. +  DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
  1724. +  return(True);
  1725. +}
  1726. +
  1727. +static int check_printdest_info(struct pack_desc* desc,
  1728. +                int uLevel, const char* id)
  1729. +{
  1730. +  desc->subformat = NULL;
  1731. +  switch( uLevel ) {
  1732. +  case 0: desc->format = "B9"; break;
  1733. +  case 1: desc->format = "B9B21WWzW"; break;
  1734. +  case 2: desc->format = "z"; break;
  1735. +  case 3: desc->format = "zzzWWzzzWW"; break;
  1736. +  default: return False;
  1737. +  }
  1738. +  if (strcmp(desc->format,id) != 0) return False;
  1739. +  return True;
  1740. +}
  1741. +
  1742. +static void fill_printdest_info(int cnum, int snum, int uLevel,
  1743. +                struct pack_desc* desc)
  1744. +{
  1745. +  char buf[100];
  1746. +  strcpy(buf,SERVICE(snum));
  1747. +  strupper(buf);
  1748. +  if (uLevel <= 1) {
  1749. +    PACK(desc,"B9",buf);    /* szName */
  1750. +    if (uLevel == 1) {
  1751. +      PACK(desc,"B21","");    /* szUserName */
  1752. +      PACK(desc,"W",0);        /* uJobId */
  1753. +      PACK(desc,"W",0);        /* fsStatus */
  1754. +      PACK(desc,"z","");    /* pszStatus */
  1755. +      PACK(desc,"W",0);        /* time */
  1756. +    }
  1757. +  }
  1758. +  if (uLevel == 2 || uLevel == 3) {
  1759. +    PACK(desc,"z",buf);        /* pszPrinterName */
  1760. +    if (uLevel == 3) {
  1761. +      PACK(desc,"z","");    /* pszUserName */
  1762. +      PACK(desc,"z",0);        /* pszLogAddr */
  1763. +      PACK(desc,"W",0);        /* uJobId */
  1764. +      PACK(desc,"W",0);        /* fsStatus */
  1765. +      PACK(desc,"z","");    /* pszStatus */
  1766. +      PACK(desc,"z","");    /* pszComment */
  1767. +      PACK(desc,"z","IBMNULL"); /* pszDrivers */
  1768. +      PACK(desc,"W",0);        /* time */
  1769. +      PACK(desc,"W",0);        /* pad1 */
  1770. +    }
  1771. +  }
  1772. +}
  1773. +
  1774. +static BOOL api_WPrintDestGetInfo(int cnum,char *param,char *data,
  1775. +                  int mdrcnt,int mprcnt,
  1776. +                  char **rdata,char **rparam,
  1777. +                  int *rdata_len,int *rparam_len)
  1778. +{
  1779. +  char *str1 = param+2;
  1780. +  char *str2 = skip_string(str1,1);
  1781. +  char *p = skip_string(str2,1);
  1782. +  char* PrinterName = p;
  1783. +  int uLevel,cbBuf;
  1784. +  struct pack_desc desc;
  1785. +  int snum;
  1786. +
  1787. +  p = skip_string(p,1);
  1788. +  uLevel = SVAL(p,0);
  1789. +  cbBuf = SVAL(p,2);
  1790. +
  1791. +  DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
  1792. +
  1793. +  /* check it's a supported varient */
  1794. +  if (strcmp(str1,"zWrLh") != 0) return False;
  1795. +  if (!check_printdest_info(&desc,uLevel,str2)) return False;
  1796. +
  1797. +  snum = lp_servicenumber(PrinterName);
  1798. +  if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
  1799. +    int pnum = lp_servicenumber(PRINTERS_NAME);
  1800. +    if (pnum >= 0) {
  1801. +      lp_add_printer(PrinterName,pnum);
  1802. +      snum = lp_servicenumber(PrinterName);
  1803. +    }
  1804. +  }
  1805. +
  1806. +  if (snum < 0) {
  1807. +    *rdata_len = 0;
  1808. +    desc.errcode = NERR_DestNotFound;
  1809. +    desc.neededlen = 0;
  1810. +  }
  1811. +  else {
  1812. +    if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1813. +    desc.base = *rdata;
  1814. +    desc.buflen = mdrcnt;
  1815. +    init_package(&desc,1,0);
  1816. +    fill_printdest_info(cnum,snum,uLevel,&desc);
  1817. +    *rdata_len = desc.usedlen;
  1818. +  }
  1819. +
  1820. +  *rparam_len = 6;
  1821. +  *rparam = REALLOC(*rparam,*rparam_len);
  1822. +  SSVALS(*rparam,0,desc.errcode);
  1823. +  SSVAL(*rparam,2,0);
  1824. +  SSVAL(*rparam,4,desc.neededlen);
  1825. +
  1826. +  DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
  1827. +  return(True);
  1828. +}
  1829. +
  1830. +static BOOL api_WPrintDestEnum(int cnum,char *param,char *data,
  1831. +                   int mdrcnt,int mprcnt,
  1832. +                   char **rdata,char **rparam,
  1833. +                   int *rdata_len,int *rparam_len)
  1834. +{
  1835. +  char *str1 = param+2;
  1836. +  char *str2 = skip_string(str1,1);
  1837. +  char *p = skip_string(str2,1);
  1838. +  int uLevel,cbBuf;
  1839. +  int queuecnt;
  1840. +  int i, n, succnt;
  1841. +  struct pack_desc desc;
  1842. +  int services = lp_numservices();
  1843. +
  1844. +  uLevel = SVAL(p,0);
  1845. +  cbBuf = SVAL(p,2);
  1846. +
  1847. +  DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
  1848. +
  1849. +  /* check it's a supported varient */
  1850. +  if (strcmp(str1,"WrLeh") != 0) return False;
  1851. +  if (!check_printdest_info(&desc,uLevel,str2)) return False;
  1852. +
  1853. +  queuecnt = 0;
  1854. +  for (i = 0; i < services; i++)
  1855. +    if (lp_print_ok(i) && lp_browseable(i))
  1856. +      queuecnt++;
  1857. +
  1858. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1859. +  desc.base = *rdata;
  1860. +  desc.buflen = mdrcnt;
  1861. +  init_package(&desc,queuecnt,0);
  1862. +
  1863. +  succnt = 0;
  1864. +  n = 0;
  1865. +  for (i = 0; i < services; i++) {
  1866. +    if (lp_print_ok(i) && lp_browseable(i)) {
  1867. +      fill_printdest_info(cnum,i,uLevel,&desc);
  1868. +      n++;
  1869. +      if (desc.errcode == NERR_Success) succnt = n;
  1870. +    }
  1871. +  }
  1872. +  *rdata_len = desc.usedlen;
  1873. +
  1874. +  *rparam_len = 8;
  1875. +  *rparam = REALLOC(*rparam,*rparam_len);
  1876. +  SSVALS(*rparam,0,desc.errcode);
  1877. +  SSVAL(*rparam,2,0);
  1878. +  SSVAL(*rparam,4,succnt);
  1879. +  SSVAL(*rparam,6,queuecnt);
  1880. +
  1881. +  DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
  1882. +  return(True);
  1883. +}
  1884. +
  1885. +static BOOL api_WPrintDriverEnum(int cnum,char *param,char *data,
  1886. +                 int mdrcnt,int mprcnt,
  1887. +                 char **rdata,char **rparam,
  1888. +                 int *rdata_len,int *rparam_len)
  1889. +{
  1890. +  char *str1 = param+2;
  1891. +  char *str2 = skip_string(str1,1);
  1892. +  char *p = skip_string(str2,1);
  1893. +  int uLevel,cbBuf;
  1894. +  int succnt;
  1895. +  struct pack_desc desc;
  1896. +
  1897. +  uLevel = SVAL(p,0);
  1898. +  cbBuf = SVAL(p,2);
  1899. +
  1900. +  DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
  1901. +
  1902. +  /* check it's a supported varient */
  1903. +  if (strcmp(str1,"WrLeh") != 0) return False;
  1904. +  if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
  1905. +
  1906. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1907. +  desc.base = *rdata;
  1908. +  desc.buflen = mdrcnt;
  1909. +  init_package(&desc,1,0);
  1910. +
  1911. +  PACK(&desc,"B41","IBMNULL");
  1912. +  succnt = (desc.errcode == NERR_Success ? 1 : 0);
  1913. +
  1914. +  *rdata_len = desc.usedlen;
  1915. +
  1916. +  *rparam_len = 8;
  1917. +  *rparam = REALLOC(*rparam,*rparam_len);
  1918. +  SSVALS(*rparam,0,desc.errcode);
  1919. +  SSVAL(*rparam,2,0);
  1920. +  SSVAL(*rparam,4,succnt);
  1921. +  SSVAL(*rparam,6,1);
  1922. +
  1923. +  DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
  1924. +  return(True);
  1925. +}
  1926. +
  1927. +static BOOL api_WPrintQProcEnum(int cnum,char *param,char *data,
  1928. +                int mdrcnt,int mprcnt,
  1929. +                char **rdata,char **rparam,
  1930. +                int *rdata_len,int *rparam_len)
  1931. +{
  1932. +  char *str1 = param+2;
  1933. +  char *str2 = skip_string(str1,1);
  1934. +  char *p = skip_string(str2,1);
  1935. +  int uLevel,cbBuf;
  1936. +  int succnt;
  1937. +  struct pack_desc desc;
  1938. +
  1939. +  uLevel = SVAL(p,0);
  1940. +  cbBuf = SVAL(p,2);
  1941. +
  1942. +  DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
  1943. +
  1944. +  /* check it's a supported varient */
  1945. +  if (strcmp(str1,"WrLeh") != 0) return False;
  1946. +  if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
  1947. +
  1948. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1949. +  desc.base = *rdata;
  1950. +  desc.buflen = mdrcnt;
  1951. +  init_package(&desc,1,0);
  1952. +
  1953. +  PACK(&desc,"B13","lpd");
  1954. +  succnt = (desc.errcode == NERR_Success ? 1 : 0);
  1955. +
  1956. +  *rdata_len = desc.usedlen;
  1957. +
  1958. +  *rparam_len = 8;
  1959. +  *rparam = REALLOC(*rparam,*rparam_len);
  1960. +  SSVALS(*rparam,0,desc.errcode);
  1961. +  SSVAL(*rparam,2,0);
  1962. +  SSVAL(*rparam,4,succnt);
  1963. +  SSVAL(*rparam,6,1);
  1964. +
  1965. +  DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
  1966. +  return(True);
  1967. +}
  1968. +
  1969. +static BOOL api_WPrintPortEnum(int cnum,char *param,char *data,
  1970. +                   int mdrcnt,int mprcnt,
  1971. +                   char **rdata,char **rparam,
  1972. +                   int *rdata_len,int *rparam_len)
  1973. +{
  1974. +  char *str1 = param+2;
  1975. +  char *str2 = skip_string(str1,1);
  1976. +  char *p = skip_string(str2,1);
  1977. +  int uLevel,cbBuf;
  1978. +  int succnt;
  1979. +  struct pack_desc desc;
  1980.  
  1981. +  uLevel = SVAL(p,0);
  1982. +  cbBuf = SVAL(p,2);
  1983. +
  1984. +  DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
  1985. +
  1986. +  /* check it's a supported varient */
  1987. +  if (strcmp(str1,"WrLeh") != 0) return False;
  1988. +  if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
  1989. +
  1990. +  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  1991. +  desc.base = *rdata;
  1992. +  desc.buflen = mdrcnt;
  1993. +  init_package(&desc,1,0);
  1994. +
  1995. +  PACK(&desc,"B13","lp0");
  1996. +  succnt = (desc.errcode == NERR_Success ? 1 : 0);
  1997. +
  1998. +  *rdata_len = desc.usedlen;
  1999. +
  2000. +  *rparam_len = 8;
  2001. +  *rparam = REALLOC(*rparam,*rparam_len);
  2002. +  SSVALS(*rparam,0,desc.errcode);
  2003. +  SSVAL(*rparam,2,0);
  2004. +  SSVAL(*rparam,4,succnt);
  2005. +  SSVAL(*rparam,6,1);
  2006. +
  2007. +  DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
  2008. +  return(True);
  2009. +}
  2010. +
  2011.  /****************************************************************************
  2012. -the buffer was too small
  2013. -****************************************************************************/
  2014. +  the buffer was too small
  2015. +  ****************************************************************************/
  2016.  static BOOL api_TooSmall(int cnum,char *param,char *data,
  2017.               int mdrcnt,int mprcnt,
  2018.               char **rdata,char **rparam,
  2019. @@ -751,8 +1923,8 @@
  2020.  
  2021.  
  2022.  /****************************************************************************
  2023. -the request is not supported
  2024. -****************************************************************************/
  2025. +  the request is not supported
  2026. +  ****************************************************************************/
  2027.  static BOOL api_Unsupported(int cnum,char *param,char *data,
  2028.                  int mdrcnt,int mprcnt,
  2029.                  char **rdata,char **rparam,
  2030. @@ -764,7 +1936,7 @@
  2031.    *rdata_len = 0;
  2032.  
  2033.    SSVAL(*rparam,0,NERR_notsupported);
  2034. -  SSVAL(*rparam,2,0); /* converter word */
  2035. +  SSVAL(*rparam,2,0);        /* converter word */
  2036.  
  2037.    DEBUG(3,("Unsupported API command\n"));
  2038.  
  2039. @@ -781,20 +1953,33 @@
  2040.    BOOL (*fn)();
  2041.    int flags;
  2042.  } api_commands[] = {
  2043. -  {"DosPrintQGetInfo",70,api_DosPrintQGetInfo,0},
  2044. -  {"NetRemoteTOD",91,api_NetRemoteTOD,0},
  2045. -  {"SetUserPassword",115,api_SetUserPassword,0},
  2046. -  {"RNetShareEnum",0,api_RNetShareEnum,0},
  2047. -  {"RDosPrintJobDel",81,api_RDosPrintJobDel,0},
  2048. -  {"PrintJobInfo",147,api_PrintJobInfo,0},
  2049. -  {"RNetServerGetInfo",13,api_RNetServerGetInfo,0},
  2050. -  {"NetWkstaGetInfo",63,api_NetWkstaGetInfo,0},
  2051. -  {NULL,-1,api_Unsupported,0}};
  2052. +  {"RNetShareEnum",    0,    api_RNetShareEnum,0},
  2053. +  {"RNetShareGetInfo",    1,    api_RNetShareGetInfo,0},
  2054. +  {"RNetServerGetInfo",    13,    api_RNetServerGetInfo,0},
  2055. +  {"RNetUserGetInfo",    56,    api_RNetUserGetInfo,0},
  2056. +  {"NetWkstaGetInfo",    63,    api_NetWkstaGetInfo,0},
  2057. +  {"DosPrintQEnum",    69,    api_DosPrintQEnum,0},
  2058. +  {"DosPrintQGetInfo",    70,    api_DosPrintQGetInfo,0},
  2059. +  {"WPrintJobEnumerate",76,    api_WPrintJobEnumerate,0},
  2060. +  {"WPrintJobGetInfo",    77,    api_WPrintJobGetInfo,0},
  2061. +  {"RDosPrintJobDel",    81,    api_RDosPrintJobDel,0},
  2062. +  {"WPrintDestEnum",    84,    api_WPrintDestEnum,0},
  2063. +  {"WPrintDestGetInfo",    85,    api_WPrintDestGetInfo,0},
  2064. +  {"NetRemoteTOD",    91,    api_NetRemoteTOD,0},
  2065. +  {"WPrintQueuePurge",    103,    api_WPrintQueuePurge,0},
  2066. +  {"WAccessGetUserPerms",105,    api_WAccessGetUserPerms,0},
  2067. +  {"SetUserPassword",    115,    api_SetUserPassword,0},
  2068. +  {"WWkstaUserLogon",    132,    api_WWkstaUserLogon,0},
  2069. +  {"PrintJobInfo",    147,    api_PrintJobInfo,0},
  2070. +  {"WPrintDriverEnum",    205,    api_WPrintDriverEnum,0},
  2071. +  {"WPrintQProcEnum",    206,    api_WPrintQProcEnum,0},
  2072. +  {"WPrintPortEnum",    207,    api_WPrintPortEnum,0},
  2073. +  {NULL,        -1,    api_Unsupported,0}};
  2074.  
  2075.  
  2076.  /****************************************************************************
  2077. -handle remote api calls
  2078. -****************************************************************************/
  2079. +  handle remote api calls
  2080. +  ****************************************************************************/
  2081.  static int api_reply(int cnum,char *outbuf,char *data,char *params,
  2082.               int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
  2083.  {
  2084. @@ -828,7 +2013,7 @@
  2085.        rparam_len > mprcnt)
  2086.      {
  2087.        reply = api_TooSmall(cnum,params,data,mdrcnt,mprcnt,
  2088. -            &rdata,&rparam,&rdata_len,&rparam_len);
  2089. +               &rdata,&rparam,&rdata_len,&rparam_len);
  2090.      }
  2091.          
  2092.  
  2093. @@ -851,8 +2036,8 @@
  2094.  }
  2095.  
  2096.  /****************************************************************************
  2097. -handle named pipe commands
  2098. -****************************************************************************/
  2099. +  handle named pipe commands
  2100. +  ****************************************************************************/
  2101.  static int named_pipe(int cnum,char *outbuf,char *name,
  2102.                uint16 *setup,char *data,char *params,
  2103.                int suwcnt,int tdscnt,int tpscnt,
  2104. @@ -871,7 +2056,7 @@
  2105.  
  2106.  /****************************************************************************
  2107.    reply to a SMBtrans
  2108. -****************************************************************************/
  2109. +  ****************************************************************************/
  2110.  int reply_trans(char *inbuf,char *outbuf)
  2111.  {
  2112.    fstring name;
  2113. @@ -937,7 +2122,7 @@
  2114.        /* Ensure this is still a trans packet (sanity check) */
  2115.        if(CVAL(inbuf, smb_com) != SMBtrans)
  2116.      {
  2117. -      DEBUG(0,("Invalid secondary trans2 packet\n"));
  2118. +      DEBUG(2,("Invalid secondary trans2 packet\n"));
  2119.        if (params) free(params);
  2120.        if (data) free(data);
  2121.        if (setup) free(setup);
  2122. diff -u -r --new-file last-version/source/nameserv.c samba-1.9.14alpha4/source/nameserv.c
  2123. --- last-version/source/nameserv.c    Sat Jul  1 01:10:56 1995
  2124. +++ samba-1.9.14alpha4/source/nameserv.c    Sun Jul  2 02:08:39 1995
  2125. @@ -908,7 +908,83 @@
  2126.    return;
  2127.  }
  2128.  
  2129. +/****************************************************************************
  2130. +reply to a name release
  2131. +****************************************************************************/
  2132. +static void reply_name_release(char *inbuf)
  2133. +{
  2134. +  pstring outbuf;
  2135. +  int rec_name_trn_id = RSVAL(inbuf,0);
  2136. +  char qname[100]="";
  2137. +  char *p = inbuf;
  2138. +  struct in_addr ip;
  2139. +  int n=0;
  2140. +  int name_type;
  2141. +  unsigned char nb_flags;
  2142. +  struct in_addr tmpip;
  2143. +  BOOL release_ok=False;
  2144. +  int reason=5;
  2145. +
  2146. +
  2147. +  bzero(outbuf,sizeof(outbuf));
  2148. +
  2149. +  name_type = name_extract(inbuf,12,qname);
  2150. +
  2151. +  p += 12;
  2152. +  p += name_len(p);
  2153. +  p += 4;
  2154. +  p += name_len(p);
  2155. +  p += 4;
  2156. +  nb_flags = CVAL(p,6);
  2157. +  p += 8;
  2158. +  putip((char *)&ip,p);
  2159. +
  2160. +  DEBUG(2,("Name release request for %s (%s) nb_flags=0x%x ntype=%d\n",
  2161. +    qname,inet_ntoa(ip),nb_flags,name_type));
  2162. +
  2163. +
  2164. +  n = find_name(qname,name_type,True);
  2165. +  if (n>=0 &&
  2166. +      !names[n].isgroup &&
  2167. +      memcmp(&names[n].ip,&ip,sizeof(ip))==0 &&
  2168. +      names[n].ttl != 0) {
  2169. +    release_ok = True;
  2170. +    names[n].valid = False;
  2171. +  }
  2172. +
  2173. +
  2174. +  /* Send a POSITIVE NAME RELEASE RESPONSE */
  2175. +  RSSVAL(outbuf,0,rec_name_trn_id);
  2176. +  CVAL(outbuf,2) = (1<<7) | (6<<3) | 4;
  2177. +  CVAL(outbuf,3) = release_ok?0:reason;
  2178. +  RSSVAL(outbuf,4,0);
  2179. +  RSSVAL(outbuf,6,1);
  2180. +  RSSVAL(outbuf,8,0);
  2181. +  RSSVAL(outbuf,10,0);  
  2182. +  p = outbuf+12;
  2183. +  strcpy(p,inbuf+12);
  2184. +  p += name_len(p);
  2185. +  RSSVAL(p,0,0x20);
  2186. +  RSSVAL(p,2,0x1);
  2187. +  RSIVAL(p,4,0); /* ttl */
  2188. +  RSSVAL(p,8,6);
  2189. +  RSSVAL(p,10,nb_flags);
  2190. +  p += 12;
  2191. +  putip(p,&ip);  
  2192. +  p += 4;
  2193. +
  2194. +  DEBUG(2,("Sending a %s name release response\n",release_ok?"positive":"negative"));
  2195. +  if (DEBUGLEVEL > 2)
  2196. +    show_nmb(outbuf);
  2197.  
  2198. +  tmpip = lastip;
  2199. +  num_good_sends++;
  2200. +  send_nmb(outbuf,PTR_DIFF(p,outbuf),&tmpip,lastport>0?lastport:137);
  2201. +
  2202. +  return;
  2203. +}
  2204. +
  2205. +
  2206.  /****************************************************************************
  2207.  reply to a name status query
  2208.  ****************************************************************************/
  2209. @@ -1163,6 +1239,12 @@
  2210.    if (opcode == 0 && qdcount==1)
  2211.      {
  2212.        reply_name_query(inbuf);
  2213. +      return;
  2214. +    }
  2215. +
  2216. +  if (!bcast && opcode == 6 && qdcount==1 && arcount==1)
  2217. +    {
  2218. +      reply_name_release(inbuf);
  2219.        return;
  2220.      }
  2221.  
  2222. diff -u -r --new-file last-version/source/printing.c samba-1.9.14alpha4/source/printing.c
  2223. --- last-version/source/printing.c    Fri Jun 30 17:32:52 1995
  2224. +++ samba-1.9.14alpha4/source/printing.c    Sat Jul  1 14:26:15 1995
  2225. @@ -25,9 +25,9 @@
  2226.  extern connection_struct Connections[];
  2227.  extern files_struct Files[];
  2228.  
  2229. +BOOL lpq_cache_reset = False;
  2230.  
  2231.  
  2232. -
  2233.  /****************************************************************************
  2234.  Build the print command in the supplied buffer. This means getting the
  2235.  print command for the service and inserting the printer name and the
  2236. @@ -101,6 +101,8 @@
  2237.    int cnum = Files[fnum].cnum;
  2238.    char *tempstr;
  2239.  
  2240. +  lpq_cache_reset = True;
  2241. +
  2242.    *syscmd = 0;
  2243.  
  2244.    if (Files[fnum].pos == -1) {
  2245. @@ -443,7 +445,7 @@
  2246.  
  2247.  
  2248.  char *stat0_strings[] = { "enabled", "online", "idle", NULL };
  2249. -char *stat1_strings[] = { "offline", "disabled", "down", NULL };
  2250. +char *stat1_strings[] = { "offline", "disabled", "down", "off", NULL };
  2251.  char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", NULL };
  2252.  
  2253.  /****************************************************************************
  2254. @@ -479,22 +481,19 @@
  2255.  
  2256.        for (i=0; stat0_strings[i]; i++)
  2257.          if (strstr(line,stat0_strings[i])) {
  2258. -      if (status->message) free(status->message);
  2259. -      status->message = strdup(line);
  2260. +      StrnCpy(status->message,line,sizeof(status->message)-1);
  2261.        status->status=LPSTAT_OK;
  2262.        return(ret);
  2263.          }
  2264.        for (i=0; stat1_strings[i]; i++)
  2265.          if (strstr(line,stat1_strings[i])) {
  2266. -      if (status->message) free(status->message);
  2267. -      status->message = strdup(line);
  2268. +      StrnCpy(status->message,line,sizeof(status->message)-1);
  2269.        status->status=LPSTAT_STOPPED;
  2270.        return(ret);
  2271.          }
  2272.        for (i=0; stat2_strings[i]; i++)
  2273.          if (strstr(line,stat2_strings[i])) {
  2274. -      if (status->message) free(status->message);
  2275. -      status->message = strdup(line);
  2276. +      StrnCpy(status->message,line,sizeof(status->message)-1);
  2277.        status->status=LPSTAT_ERROR;
  2278.        return(ret);
  2279.          }
  2280. @@ -543,7 +542,9 @@
  2281.  
  2282.    sprintf(outfile,"/tmp/lpq.%08x",str_checksum(syscmd));
  2283.  
  2284. -  if (cachetime && stat(outfile,&sbuf) == 0 && 
  2285. +  if (!lpq_cache_reset && 
  2286. +      cachetime && 
  2287. +      stat(outfile,&sbuf) == 0 && 
  2288.        (time(NULL) - sbuf.st_mtime)<cachetime) {
  2289.      DEBUG(3,("Using cached lpq output\n"));
  2290.      dorun = False;
  2291. @@ -553,7 +554,8 @@
  2292.      int fd = open(outfile,O_RDWR);
  2293.      if (fd >= 0) {
  2294.        flock(fd,LOCK_EX);
  2295. -      if (cachetime && fstat(fd,&sbuf) == 0 && 
  2296. +      if (!lpq_cache_reset &&
  2297. +      cachetime && fstat(fd,&sbuf) == 0 && 
  2298.        (time(NULL) - sbuf.st_mtime)<cachetime) {
  2299.      DEBUG(3,("Using cached lpq output\n"));
  2300.      dorun = False;
  2301. @@ -569,12 +571,14 @@
  2302.      DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
  2303.    }
  2304.  
  2305. +  lpq_cache_reset = False;
  2306. +
  2307.    f = fopen(outfile,"r");
  2308.    if (!f)
  2309.      return(0);
  2310.  
  2311.    if (status)
  2312. -    status->message = NULL;
  2313. +    strcpy(status->message,"");
  2314.        
  2315.    while (fgets(line,sizeof(pstring),f))
  2316.      {
  2317. diff -u -r --new-file last-version/source/server.c samba-1.9.14alpha4/source/server.c
  2318. --- last-version/source/server.c    Fri Jun 30 15:48:31 1995
  2319. +++ samba-1.9.14alpha4/source/server.c    Sat Jul  1 14:49:28 1995
  2320. @@ -1332,7 +1332,7 @@
  2321.  /****************************************************************************
  2322.    find a service entry
  2323.  ****************************************************************************/
  2324. -static int find_service(char *service)
  2325. +int find_service(char *service)
  2326.  {
  2327.     int iService;
  2328.  
  2329. @@ -3571,8 +3571,10 @@
  2330.        extern int keepalive;
  2331.  
  2332.        /* check for socket failure */
  2333. -      if (errno == EBADF)
  2334. +      if (errno == EBADF) {
  2335. +        DEBUG(2,("%s Bad file descriptor - exiting\n",timestring()));
  2336.          return;
  2337. +      }
  2338.  
  2339.        t = time(NULL);
  2340.  
  2341. @@ -3593,11 +3595,16 @@
  2342.          clean_share_files();
  2343.  
  2344.        /* automatic timeout if all connections are closed */      
  2345. -      if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
  2346. +      if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
  2347. +        DEBUG(2,("%s Closing idle connection\n",timestring()));
  2348.          return;
  2349. +      }
  2350.  
  2351.        if (keepalive && (counter-last_keepalive)>keepalive) {
  2352. -        if (!send_keepalive(Client)) return;
  2353. +        if (!send_keepalive(Client)) {
  2354. +          DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
  2355. +          return;
  2356. +        }
  2357.          last_keepalive = counter;
  2358.        }
  2359.  
  2360. @@ -3614,8 +3621,10 @@
  2361.            allidle = False;
  2362.            }
  2363.  
  2364. -      if (allidle && num_connections_open>0)
  2365. +      if (allidle && num_connections_open>0) {
  2366. +        DEBUG(2,("%s Closing idle connection 2\n",timestring()));
  2367.          return;
  2368. +      }
  2369.      }
  2370.  
  2371.        msg_type = CVAL(InBuffer,0);
  2372. diff -u -r --new-file last-version/source/smb.h samba-1.9.14alpha4/source/smb.h
  2373. --- last-version/source/smb.h    Fri Jun 30 15:33:27 1995
  2374. +++ samba-1.9.14alpha4/source/smb.h    Sat Jul  1 14:01:04 1995
  2375. @@ -297,7 +297,7 @@
  2376.  
  2377.  typedef struct
  2378.  {
  2379. -  char *message;
  2380. +  fstring message;
  2381.    int status;
  2382.  }  print_status_struct;
  2383.  
  2384. @@ -548,6 +548,7 @@
  2385.  };
  2386.  
  2387.  /* and a few prototypes */
  2388. +int find_service(char *service);
  2389.  int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
  2390.  int smb_offset(char *p,char *buf);
  2391.  void sync_file(int fnum);
  2392. diff -u -r --new-file last-version/source/trans2.c samba-1.9.14alpha4/source/trans2.c
  2393. --- last-version/source/trans2.c    Fri Jun 30 23:04:49 1995
  2394. +++ samba-1.9.14alpha4/source/trans2.c    Sat Jul  1 11:13:37 1995
  2395. @@ -385,21 +385,18 @@
  2396.        break;
  2397.  
  2398.      case 3:
  2399. -      if(requires_resume_key) {
  2400. -    SIVAL(p,0,reskey);
  2401. -    p += 4;
  2402. -      }
  2403. -      SIVAL(p,0,29+strlen(fname)+1);
  2404. +      SIVAL(p,0,reskey);
  2405.        put_dos_date2(p,4,cdate);
  2406.        put_dos_date2(p,8,adate);
  2407.        put_dos_date2(p,12,mdate);
  2408.        SIVAL(p,16,size);
  2409.        SIVAL(p,20,1024);
  2410.        SSVAL(p,24,mode);
  2411. -      CVAL(p,28) = strlen(fname);
  2412. -      strcpy(p + 29, fname);
  2413. -      name_ptr = p+29;
  2414. -      p += 29 + strlen(fname) + 1;
  2415. +      SIVAL(p,26,4);
  2416. +      CVAL(p,30) = strlen(fname);
  2417. +      strcpy(p+31, fname);
  2418. +      name_ptr = p+31;
  2419. +      p += 31 + strlen(fname) + 1;
  2420.        break;
  2421.  
  2422.      case 4:
  2423. diff -u -r --new-file last-version/source/util.c samba-1.9.14alpha4/source/util.c
  2424. --- last-version/source/util.c    Sat Jul  1 01:04:24 1995
  2425. +++ samba-1.9.14alpha4/source/util.c    Sat Jul  1 14:56:52 1995
  2426. @@ -3049,6 +3049,10 @@
  2427.    if(fstat(fd, &st)<0)
  2428.      return -1;
  2429.  
  2430. +#ifdef S_ISFIFO
  2431. +  if (S_ISFIFO(st.st_mode)) return 0;
  2432. +#endif
  2433. +
  2434.    if(st.st_size == len)
  2435.      return 0;
  2436.    if(st.st_size > len)
  2437. diff -u -r --new-file last-version/source/version.h samba-1.9.14alpha4/source/version.h
  2438. --- last-version/source/version.h    Sun Jul  2 02:10:34 1995
  2439. +++ samba-1.9.14alpha4/source/version.h    Sun Jul  2 02:17:52 1995
  2440. @@ -1 +1 @@
  2441. -#define VERSION "1.9.14alpha3"
  2442. +#define VERSION "1.9.14alpha4"
  2443.